# Can't get value from hash in XML document

**URL:** <https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897>\
**Category:** Logstash\
**Created:** [April 7, 2022, 5:53pm UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897 "2022-04-07T17:53:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![duanra22](https://avatars.discourse-cdn.com/v4/letter/d/3ec8ea/32.png) [@duanra22](https://discuss.elastic.co/u/duanra22)\
**Post date:** [April 7, 2022, 5:53pm UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897/1 "2022-04-07T17:53:08Z")

</div>

Hello,

I'm struggling with an XML document that I am processing  
The part that is annoying me is something like

```auto
<Informations>
	<Specs>
		<Dtl>
			<Code>code1</Code>
			<Value>value1</Value>
		</Dtl>
		<Dtl>
			<Code>code2</Code>
			<Value>value2</Value>
		</Dtl>
		<Dtl>
			<Code>code3</Code>
			<Value>value3</Value>
		</Dtl>
	</Specs>
</Informations>

```

I want to be able to create a new field if I find a specific value in `<Code>` tag.  
For example, if code2 is present I want to create a field containing value2.

The thing is that I don't know how much `<Dtl>` tags I will have in the document.

With only one `<Dtl>` I could use a mutate filter like

```auto
if [Informations][Specs][Dtl][Code] and [Informations][Specs][Dtl][Code] == "code2" {
    mutate {
      add_field => {"[newField]" => "%{[Informations][Specs][Dtl][Value]}"}
    }
}

```

However, I may have one but also many more` <Dtl>` tags.

I have been able to determine that this is a hash type with a ruby filter like

```auto
ruby {
    code => "
          case event.get('[Informations][Specs]')
                  when Hash
                    event.set('[Example]', 'This is a hash')
                  end 
    "
}

```

But I have no idea how to iterate over it and look for a specific code.

If anyone has an idea that would be a greate help !

Thank you

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 7, 2022, 7:35pm UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897/2 "2022-04-07T19:35:42Z")

</div>

I would expect [Informations][Specs] to be an array, not a hash (unless it contains a single Dtl and you have set force\_array to be false).

You could try

```
ruby {
    code => '
        specs = event.get("[Informations][Specs]")
        if specs.is_a? Array
            specs.each { |x|
                if x["Code"] == "code2"
                    event.set("[newField]", x["Value"])
              end 
            }
        end
    '
}
```

---

<div class="post-metadata">

**Author:** ![duanra22](https://avatars.discourse-cdn.com/v4/letter/d/3ec8ea/32.png) [@duanra22](https://discuss.elastic.co/u/duanra22)\
**Post date:** [April 8, 2022, 10:03am UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897/3 "2022-04-08T10:03:20Z")

</div>

Hello @Badger thanks for your answer.  
I actually set force\_array to false in an xml filter you are right, this is why the field is a hash (I didn't think it would have this impact)

```auto
xml {
    source => "message"
    store_xml => true
    target => "doc"
    force_array => "false"
 }

```

(so everything is under the tag doc but I didn't include it in my question.)

In my logstash conf, I am also using the mutate filter to add fields based on other values from my XML document. (and it works fine)

Do you think I should only use a ruby filter and unset force\_array to false ?

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 8, 2022, 2:19pm UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897/4 "2022-04-08T14:19:38Z")

</div>

Only you can decide whether force\_array should be true or false, it depends on how it affects all the other elements of the XML.

You could modify the ruby filter to check whether [Informations][Specs] is a hash or an array and process each appropriately.

---

<div class="post-metadata">

**Author:** ![duanra22](https://avatars.discourse-cdn.com/v4/letter/d/3ec8ea/32.png) [@duanra22](https://discuss.elastic.co/u/duanra22)\
**Post date:** [April 12, 2022, 7:06am UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897/5 "2022-04-12T07:06:02Z")

</div>

Thank you Badger, I will let my xml filter as it was because it makes it much more easier to process the documents I will receive.

I will try to add the process for a hash, I guess I just have to check each (key, value)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [May 10, 2022, 7:06am UTC](https://discuss.elastic.co/t/cant-get-value-from-hash-in-xml-document/301897/6 "2022-05-10T07:06:43Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
