# XML filter - processing of an array of values

**URL:** https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601
**Category:** Logstash
**Created:** [August 16, 2021, 8:30pm UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601 "2021-08-16T20:30:45Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Robo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/robo/32/38295_2.png) [@Robo](https://discuss.elastic.co/u/Robo)
#### Post date: [August 16, 2021, 8:30pm UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601/1 "2021-08-16T20:30:45Z")

</div>

We're processing some xml events using the xml filter.  
The filter setup it's quite simple:

```auto
filter {
    xml {
      source => "message"
      target => "xml"
    }
}

```

This filter generates two fields with an array of values:  
xml.results.Name: ["OrderId","CaseId","Timestamp"]  
xml.results.Value: ["123456","987654","1629106126536"]

The goal is to create new fields based on the Name and Value:  
xml.results.Name.OrderId: "123456"  
xml.results.Name.CaseId: "987654"  
...

As there are hundreds of different field names the "xpath" definition is not good solution for us.  
Is there an option in logstash how to do it?

So far we tried to do it with a ruby script:

```auto
  ruby {
        code => '
          v = event.get("[xml][results][Value]")
          k = event.get("[xml][results][Name]")
          k.each_index { |i|
            event.set("[xml][results][Name][" + k[i] + "]", v[i] ) 
          }
        '
      }

```

But it did not worked because of following error:

```auto
Ruby exception occurred: undefined method `each_with_index' for nil:NilClass

```

Thanks! 🙂

---

<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: [August 16, 2021, 8:52pm UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601/2 "2021-08-16T20:52:53Z")

</div>

> [@Robo](#):
>
> `undefined method `each\_with\_index' for nil:NilClass`

That is telling you that k is nil, which means you are processing an event where the [xml][results][Name] field does not exist. I would wrap the k.each\_index with

```
if k.method_defined?(each_index) and v.method_defined?(each_index) {
...
}

```

---

<div class="post-metadata">

### Author: ![Robo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/robo/32/38295_2.png) [@Robo](https://discuss.elastic.co/u/Robo)
#### Post date: [August 17, 2021, 9:38am UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601/3 "2021-08-17T09:38:48Z")

</div>

Thanks for the hint!

I tried this:

```auto
  ruby {
        code => '
          v = event.get("[xml][results][Value]")
          k = event.get("[xml][results][Name]")
		  if k.method_defined?(each_index) and v.method_defined?(each_index) {
            k.each_index { |i|
                event.set("[xml][results][Name][" + k[i] + "]", v[i] ) 
            }
		  }
        '
      }

```

But following error appeared:

```auto
[2021-08-17T11:29:13,485][FATAL][org.logstash.Logstash] Logstash stopped processing because of an error: (SyntaxError) (ruby filter code):11: syntax error, unexpected end-of-file

org.jruby.exceptions.SyntaxError: (SyntaxError) (ruby filter code):11: syntax error, unexpected end-of-file

        at org.jruby.RubyKernel.eval(org/jruby/RubyKernel.java:1048) ~[jruby-complete-9.2.13.0.jar:?]

```

The second question is why the field does not exist? We can see the field name and an array of values in the event json (as described in the 1st post).

---

<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: [August 17, 2021, 2:44pm UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601/4 "2021-08-17T14:44:32Z")

</div>

> [@Robo](#):
>
> `syntax error, unexpected end-of-file`

My bad. A Ruby if statement does not take a code block. It should be

```
if k.method_defined?(each_index) and v.method_defined?(each_index)
...
end

```

Since [xml][results][Name] already exists as an array the event.set may fail telling you that it cannot coerce a string to an integer. You may need to

```
k = event.get("[xml][results][Name]")
event.remove("[xml][results][Name]")

```

Personally I would use string interpolation, although your way should also work

```
event.set("[xml][results][Name][#{k[i]}]", v[i] )

```

---

<div class="post-metadata">

### Author: ![Robo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/robo/32/38295_2.png) [@Robo](https://discuss.elastic.co/u/Robo)
#### Post date: [August 17, 2021, 2:55pm UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601/5 "2021-08-17T14:55:23Z")

</div>

Thanks a lot! This did the trick at the end.

---

<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: [September 14, 2021, 2:55pm UTC](https://discuss.elastic.co/t/xml-filter-processing-of-an-array-of-values/281601/6 "2021-09-14T14:55:47Z")

</div>

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