# Create nested field with XPath

**URL:** <https://discuss.elastic.co/t/create-nested-field-with-xpath/98230>\
**Category:** Logstash\
**Created:** [August 24, 2017, 12:09pm UTC](https://discuss.elastic.co/t/create-nested-field-with-xpath/98230 "2017-08-24T12:09:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cadoman](https://avatars.discourse-cdn.com/v4/letter/c/da6949/32.png) [@cadoman](https://discuss.elastic.co/u/cadoman)\
**Post date:** [August 24, 2017, 12:09pm UTC](https://discuss.elastic.co/t/create-nested-field-with-xpath/98230/1 "2017-08-24T12:09:06Z")

</div>

I have an XML structure

```
<Event>
  <Core Id="10233" />
  <Parameters>
      <Parameter EngValue="1.0" DecValue="1.0" />
      <Parameter EngValue="GCOM" />
      <Parameter EngValue="1.0" DecValue="1.0" />
  </Parameters>
</Event>

```

I'd like logstash to output this structure :

```
{
  "CoreID" : "10233",
  "Parameter" : [
    {
      "EngValue" : "1.0",
      "DecValue" : "1.0"
    },
    {
      "EngValue" : "GCOM"
    },
    {
      "EngValue" : "1.0",
      "DecValue" : "1.0"
    }
  ]
}

```

I have this mapping in ES :

```
"mappings" : {
  "logs" : {
    "properties" : {
      "CoreId" :{
        "type" : "text"
      },
      "Parameter" : {
        "type" : "nested",
        "properties" : {
          "DecValue" : {
            "type" : "float"
          },
          "EngValue" : {
            "type" : "text"
          }
        }
      }
    }
  }
} 

```

With the XML filter I tried :

```
xpath => [
    "/Event/Core/@Id", "CoreID",
    "/Event/Parameters/Parameter/@DecValue", "[Parameter][DecValue]",
    "/Event/Parameters/Parameter/@EngValue", "[Parameter][EngValue]",
]

```

But so far I only got this :

```
{
  "CoreID" : "10233",
  "Parameter" : {
      "EngValue" : ["1.0", "GCOM", "1.0"],
      "DecValue" : ["1.0", "1.0"]
    }
}

```

Any idea how I can achieve this?  
How can I make "Parameter" the array instead of its attributes?

---

<div class="post-metadata">

**Author:** ![magnusbaeck](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/magnusbaeck/32/44943_2.png) [@magnusbaeck](https://discuss.elastic.co/u/magnusbaeck)\
**Post date:** [August 24, 2017, 8:09pm UTC](https://discuss.elastic.co/t/create-nested-field-with-xpath/98230/2 "2017-08-24T20:09:52Z")

</div>

It appears you're asking the same question as here:

> [@Xml parser with xpath giving wrong result in xml filter plugin](https://discuss.elastic.co/t/xml-parser-with-xpath-giving-wrong-result-in-xml-filter-plugin/97666/):
>
> Hi All i am having a xml filter, which looks like this xml { source =\> "message" target =\> "message\_parsed" add\_tag =\> ["xml\_parsed"] remove\_namespaces =\> true store\_xml =\> true force\_array =\> true xpath =\> ["/table/row/number/text()","number"] } Here i am getting only 1 record. I am expecting 5 records Under the column "number" i am getting value as comma seperated 123,124,125,126,127 My expectation …

---

<div class="post-metadata">

**Author:** ![cadoman](https://avatars.discourse-cdn.com/v4/letter/c/da6949/32.png) [@cadoman](https://discuss.elastic.co/u/cadoman)\
**Post date:** [August 25, 2017, 7:06am UTC](https://discuss.elastic.co/t/create-nested-field-with-xpath/98230/3 "2017-08-25T07:06:28Z")

</div>

I almost have the same problem.  
But I'm not sure that this solution could work for me :

> [@Use of Split Filter for more than 1 fields, it is possible](https://discuss.elastic.co/t/use-of-split-filter-for-more-than-1-fields-it-is-possible/97687/3):
>
> The split filter acts on a single field. You can use a ruby filter to join the elements of each array into another array so that you have this: { ... "field\_to\_split": [["A", "E", "W", "Q"], ... ] } Then feed field\_to\_split to a split filter, and use another filter or two to split the array back into discrete fields.

Right after the XML filter my fields look like this :

```
"Parameter" : {
   "EngValue" : ["1.0", "GCOM", "1.0"],
   "DecValue" : ["1.0", "1.0"]
 }

```

And I can't just join the elements of each array : For each element of "EngValue", I don't know the corresponding element in "DecValue" (since "DecValue" is optional).  
I could do it if I had this after the XML filter :

```
"Parameter" : {
   "EngValue" : ["1.0", "GCOM", "1.0"],
   "DecValue" : ["1.0", "" , "1.0"]
 }

```

Please notice that I don't want to split my values in multiple events. I want to put them in a "Parameter" array ("Parameter" is a nested object).

---

<div class="post-metadata">

**Author:** ![cadoman](https://avatars.discourse-cdn.com/v4/letter/c/da6949/32.png) [@cadoman](https://discuss.elastic.co/u/cadoman)\
**Post date:** [August 30, 2017, 8:08am UTC](https://discuss.elastic.co/t/create-nested-field-with-xpath/98230/4 "2017-08-30T08:08:49Z")

</div>

The solution was to use a ruby filter instead of XPath :

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

  ruby {
      code => '
        event.set("Parameter", event.get("[parsed][Parameters][0][Parameter]"))
        event.set("CoreId", event.get("[parsed][Core][0][Id]"))
      '
  }

  mutate {
    remove_field => ["message", "parsed"]
  }
}

```

This answer comes from Stack overflow : [https://stackoverflow.com/questions/45938870/handle-nested-object-with-logstah-and-xpath](https://stackoverflow.com/questions/45938870/handle-nested-object-with-logstah-and-xpath)

---

<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 27, 2017, 8:08am UTC](https://discuss.elastic.co/t/create-nested-field-with-xpath/98230/5 "2017-09-27T08:08:49Z")

</div>

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