# Xml filter: Unable to get parent and child attributes in one row

**URL:** <https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643>\
**Category:** Logstash\
**Created:** [January 9, 2018, 6:07am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643 "2018-01-09T06:07:11Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![robert2](https://avatars.discourse-cdn.com/v4/letter/r/e8c25b/32.png) [@robert2](https://discuss.elastic.co/u/robert2)\
**Post date:** [January 9, 2018, 6:07am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/1 "2018-01-09T06:07:11Z")

</div>

Hi Team  
I am new to Kibana, logstash. I am trying push xml (generated as output of nunit) in logstash. I want to have the xml elements attributes, its Parents attributes and child attributes in the same row in Kibana.  
However, i can get only the xml elements attribute. Parent and child attributes are not generated in the same row.

Below is the xml file:

```auto
<test-suite type="TestFixture" name="bootAPIs" executed="True" result="Failure" success="False" time="12.811" asserts="0">
  <results>
    <test-case name="NunitBETests.bootAPIs.GetSeriescount" executed="True" result="Success" success="True" time="0.944" asserts="0">
      <reason name="NeededforBooting">
        <message />
      </reason>
    </test-case>
    <test-case name="NunitBETests.bootAPIs.GetData" executed="True" result="Success" success="True" time="0.910" asserts="0">
      <reason>
        <message />
      </reason>
    </test-case>
    <test-case name="NunitBETests.bootAPIs.GetToken" executed="True" result="Success" success="True" time="0.462" asserts="0">
      <reason>
        <message />
        e
      </reason>
    </test-case>
  </results>
</test-suite>

```

Below is Logstash Config File I am using:

```auto
input { stdin { } }
filter {
  xml {
   store_xml => false
   source => "message"
   xpath =>
   [
    "//test-case/@name", "testcase",
	"//test-case/@result", "res",
	"//test-case/../../@name", "suitename",
	"//test-case/reason/@name","reasonattr",
	"//test-case/@time", "timetest"
   ]
}
 
date {
    match => ["date" , "dd-MM-yyyy HH:mm:ss"]
    timezone => "Europe/Amsterdam"
}

 
}

output {
 
 elasticsearch {
  action => "index"
  index => "xml12"
  hosts => ["localhost:9200"]
  
 
 }
 
 stdout { codec => rubydebug }
}

```

Result:  
I am getting this output:

```auto
{
       "message" => " <test-case name=\"NunitBETests.bootAPIs.GetSeriescount\" executed=\"True\" result=\"Success\" success=\"True\" time=\"0.462\" asserts=\"0\">\r",
      "testcase" => [
        [0] "NunitBETests.bootAPIs.GetSeriescount"
    ],
           "res" => [
        [0] "Success"
    ],

          "host" => "DESKTOP-PC8JBMK"
}

```

However I am want to capture parent attribute of "testcase" node (that is "suitename") and child attribute of "testcase" xmlnode (that is "reasonattr") in same row.  
Something like below is what i want to have:

```auto
{
       "message" => " <test-case name=\"NunitBETests.bootAPIs.GetSeriescount\" executed=\"True\" result=\"Success\" success=\"True\" time=\"0.462\" asserts=\"0\">\r",
      "testcase" => [
        [0] "NunitBETests.bootAPIs.GetSeriescount"
    ],
           "res" => [
        [0] "Success"
    ],
	        "suitename" => [
        [0] "bootAPIs"
    ],
	    "reasonattr" => [
        [0] "NeededforBooting"
    ],
		
    "@timestamp" => 2018-01-09T05:53:07.678Z,
      "@version" => "1",
      "timetest" => [
        [0] "0.462"
    ],
          "host" => "DESKTOP-PC8JBMK"
}

```

Please let me know what I am missing here.

---

<div class="post-metadata">

**Author:** ![robert2](https://avatars.discourse-cdn.com/v4/letter/r/e8c25b/32.png) [@robert2](https://discuss.elastic.co/u/robert2)\
**Post date:** [January 9, 2018, 6:22am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/3 "2018-01-09T06:22:00Z")

</div>

Uploading the xml file as png, as i was unable to paste it here: Apologies!!!

 ![xml](https://us1.discourse-cdn.com/elastic/original/3X/3/6/364554e6dd80a0039049a47098c18e791460105e.PNG)

---

<div class="post-metadata">

**Author:** ![guyboertje](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/guyboertje/32/31592_2.png) [@guyboertje](https://discuss.elastic.co/u/guyboertje)\
**Post date:** [January 9, 2018, 5:27pm UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/4 "2018-01-09T17:27:54Z")

</div>

I think that because you are not feeding the whole xml file into `stdin`, the xpath list is failing on the `../../` and not processing the rest. Try moving the `"//test-case/../../@name", "suitename",` to the bottom.  
Aslo try feeding the full xml into stdin.  
see `"message" => " <test-case`

---

<div class="post-metadata">

**Author:** ![guyboertje](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/guyboertje/32/31592_2.png) [@guyboertje](https://discuss.elastic.co/u/guyboertje)\
**Post date:** [January 9, 2018, 5:52pm UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/5 "2018-01-09T17:52:11Z")

</div>

With the full xml message, this worked for me...

```auto
filter {
  xml {
   store_xml => false
   source => "message"
   xpath =>
   [
    "/test-suite/@name", "suitename",
    "//test-case[1]/@name", "testcase",
    "//test-case[1]/@result", "res",
    "//test-case[1]/reason/@name","reasonattr",
    "//test-case[1]/@time", "timetest"
   ]
  }
}

```

---

<div class="post-metadata">

**Author:** ![robert2](https://avatars.discourse-cdn.com/v4/letter/r/e8c25b/32.png) [@robert2](https://discuss.elastic.co/u/robert2)\
**Post date:** [January 10, 2018, 6:56am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/6 "2018-01-10T06:56:53Z")

</div>

> [@guyboertje](#):
>
> xml {  
> store\_xml =\> false  
> source =\> "message"  
> xpath =\>  
> [  
> "/test-suite/@name", "suitename",  
> "//test-case[1]/@name", "testcase",  
> "//test-case[1]/@result", "res",  
> "//test-case[1]/reason/@name","reasonattr",  
> "//test-case[1]/@time", "timetest"  
> ]  
> }

thanks Guy!!!, you rightly pointed out that the xml that I was passing was not a complete "message"... helps a lot.

Now the xml file is processed as a single unit, however am yet not able to get the expected result.

I tried options like  
force\_array =\> false, force\_content =\> true  
and variations in xpath like:

```
xpath =>

```

[  
"/test-suite/@name", "suitename",  
"//test-case[1]/@name", "testcase",  
"//test-case[1]/@result", "res",  
"//test-case[1]/reason/@name","reasonattr",  
"//test-case[1]/@time", "timetest"  
]

xpath =\>  
[  
"/test-suite/@name", "suitename",  
"//test-case[_]/@name", "testcase",  
"//test-case[_]/@result", "res",  
"//test-case[_]/reason/@name","reasonattr",  
"//test-case[_]/@time", "timetest"  
]

xpath =\>  
[  
"/test-suite/results/test-case/@name","testcase",  
"/test-suite/@name", "suitename"  
]

but i got output like below in almost all cases, here the data of all testcases is packed in a single row:

{  
"suitename" =\> [  
[0] "bootAPIs"  
],  
"timetest" =\> [  
[0] 1.582,  
[1] 0.939,  
[2] 0.91,  
[3] 0.921,  
[4] 1.574,  
[5] 0.908,  
[6] 0.913,  
[7] 1.787,  
[8] 0.903,  
[9] 0.944,  
[10] 0.91,  
[11] 0.462  
],  
"testcase" =\> [  
[0] "NunitBETests.bootAPIs.GetSeriesContent",  
[1] "NunitBETests.bootAPIs.GetSeriesContent",  
[2] "NunitBETests.bootAPIs.GetToken",  
[3] "NunitBETests.bootAPIs.GetDomainPermittedSubscriptions",  
[4] "NunitBETests.bootAPIs.GetEPGMultiChannelProgram",  
[5] "NunitBETests.bootAPIs.GetItemFromList",  
[6] "NunitBETests.bootAPIs.GetMenu",  
[7] "NunitBETests.bootAPIs.GetRecordings",  
[8] "NunitBETests.bootAPIs.GetSecuredSiteGuid",  
[9] "NunitBETests.bootAPIs.GetSeriesRecordings",  
[10] "NunitBETests.bootAPIs.GetUserData",  
[11] "NunitBETests.bootAPIs.RefreshAccessToken"  
],  
"@version" =\> "1",  
"host" =\> "DESKTOP-PC8JBMK",  
"res" =\> [  
[0] "Failure",  
[1] "Success",  
[2] "Success",  
[3] "Success",  
[4] "Success",  
[5] "Success",  
[6] "Success",  
[7] "Success",  
[8] "Success",  
[9] "Success",  
[10] "Success",  
[11] "Success"  
],

What I am wanting is each of the testcase attribute, Suite Name attribute (parent of testcase) to be collected as a single row for EACH testcase present in xml file.  
Something like below is what i Want to get:

```
	  {
		 "suitename" => [
			[0] "bootAPIs"
		],
		  "timetest" => [
			[0] 1.582,
			
		],
		  "testcase" => [
			[0] "NunitBETests.bootAPIs.GetSeriescContent",
			
		],
		  "@version" => "1",
			  "host" => "DESKTOP-PC8JBMK",
			   "res" => [
			[0] "Failure",
		   
		],
	}

	{
		 "suitename" => [
			[1] "bootAPIs"
		],
		  "timetest" => [
			[1] 0.939,
			
		],
		  "testcase" => [
			[1] ""NunitBETests.bootAPIs.bootAPIs.GetSeriescContent"",
			
		],
		  "@version" => "1",
			  "host" => "DESKTOP-PC8JBMK",
			   "res" => [
			[1] "Success",
		   
		],
	}

	{
		 "suitename" => [
			[2] "bootAPIs"
		],
		  "timetest" => [
			[2] 0.91,
			
		],
		  "testcase" => [
			[2] "NunitBETests.bootAPIs.GetToken"",
			
		],
		  "@version" => "1",
			  "host" => "DESKTOP-PC8JBMK",
			   "res" => [
			[2] "Success",
		   
		],
	}

```

Please let me know, how I could get this done.

---

<div class="post-metadata">

**Author:** ![guyboertje](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/guyboertje/32/31592_2.png) [@guyboertje](https://discuss.elastic.co/u/guyboertje)\
**Post date:** [January 10, 2018, 11:00am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/7 "2018-01-10T11:00:51Z")

</div>

Maybe. If you really got to know XPath.

It seems to me that you want separate events for each `test-case` but with the @name of `test-suite` carried into each `test-case` event.

I think this can be done. It would involve two xml filter stages with a `split` filter in between.  
Use this [online XPath tester](https://www.freeformatter.com/xpath-tester.html#ad-output)

1. 1st xml filter, add two fields  
`"//test-case/../../@name", "suitename",`  
`"//test-case", "test-cases"`
2. Split filter, split on `test-cases`  
`field => "test-cases"`  
`target => "test-case"`  
this should create X number of new events all with `suitename` and `test-case` with xml content`.
3. 2nd xml filter, add the other fields.  
`"/test-case/@name", "testcase",`  
`"/test-case/@result", "res",`  
`"/test-case/reason/@name","reasonattr",`  
`"/test-case/@time", "timetest"`  
Remember to drop any fields you no longer need.  
Now elasticsearch and kibana have a single doc structure of test case to work with.

Good Luck.

---

<div class="post-metadata">

**Author:** ![robert2](https://avatars.discourse-cdn.com/v4/letter/r/e8c25b/32.png) [@robert2](https://discuss.elastic.co/u/robert2)\
**Post date:** [January 11, 2018, 5:30am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/8 "2018-01-11T05:30:10Z")

</div>

Thanks a ton Guy!!!

With all your suggestions I could finally come up with what i wanted.

Pasting here the complete details, just in case that it may assit some one else tooo...

Thanks again!

Problem statement:  
Below xml is an output generate out of Nunit . I need to collect attributes of all test-case nodes  
along with the attributes of its Parent and child nodes in a single event per testcase so that every event generated by Logstash has testcase name, testsuite name(parent node) and Failure message (child node) for all testcases in the xml.

XMl below:

 ycaddztg mg kuxxlc jlsb oagfymbn 

Logtash filter below

input { stdin { }

}  
filter {  
xml {

store\_xml =\> true  
target =\> "poc"  
source =\> "message"

}  
split {  
field =\> "poc[results][0][test-suite][0][results][0][test-suite]"  
}

split {  
field =\> "poc[results][0][test-suite][0][results][0][test-suite][results][0][test-case]"  
}

date {  
match =\> ["date" , "dd-MM-yyyy HH:mm:ss"]  
timezone =\> "Europe/Amsterdam"  
}

mutate {  
add\_field =\> { "number22" =\> "%{poc[results][0][test-suite][0][results][0][test-suite][name]}" }  
add\_field =\> { "name22" =\> "%{poc[results][0][test-suite][0][results][0][test-suite][results][0][test-case][name]}" }  
add\_field =\> { "res22" =\> "%{poc[results][0][test-suite][0][results][0][test-suite][results][0][test-case][result]}" }  
add\_field =\> { "reason22" =\> "%{poc[results][0][test-suite][0][results][0][test-suite][results][0][test-case][failure][0][message][0]}" }

}

if [reason22] == "%{poc[results][0][test-suite][0][results][0][test-suite][results][0][test-case][failure][0][message][0]}" {  
mutate { update =\> { "reason22" =\> "" } }  
}  
}  
output {  
elasticsearch {  
action =\> "index"  
index =\> "xm64"  
hosts =\> ["localhost:9200"]  
}  
stdout { codec =\> rubydebug }  
}

---

<div class="post-metadata">

**Author:** ![robert2](https://avatars.discourse-cdn.com/v4/letter/r/e8c25b/32.png) [@robert2](https://discuss.elastic.co/u/robert2)\
**Post date:** [January 11, 2018, 8:38am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/9 "2018-01-11T08:38:03Z")

</div>

```
    <test-suite type="Assembly" name="C:\vinayDoNotDelete\ComponentTestallFiles\Softwares\OtherCsharpSOlutionsunitBETests\bin\Debugunitbetests.exe" executed="True" result="Failure" success="False" time="18.987" asserts="0">
      <results>
        <test-suite type="Namespace" name="NunitBETests" executed="True" result="Failure" success="False" time="18.978" asserts="0">
          <results>
            <test-suite type="TestFixture" name="bootAPIs" executed="True" result="Failure" success="False" time="12.811" asserts="0">
              <results>
                <test-case name="NunitBETests.bootAPIs.GetMOvieFilter" executed="True" result="Failure" success="False" time="1.582" asserts="0">
                  <failure>
                    ycaddztg
                    <message>
                      <![CDATA[Either there are no linear channels or response is incorrect,
     REQUEST is : {"initObj":{"Locale":{"LocaleLanguage":"","LocaleCountry":"","LocaleDevice":"","LocaleUserState":"Unknown"},"Platform":"ConnectedTV","SiteGuid":"958863","DomainID":543335,"UDID":"616439088037","ApiUser":"tvpapi_185si","ApiPass":"A2d4G6","Token":""},"ChannelID":"3407167","picSize":"302x170","pageSize":0,"pageIndex":0,"orderBy":"None","tagsMetas":[],"cutWith":"AND"}
     RESPONSE is : []]]>
                    </message>
                    <stack-trace>
                      <![CDATA[at NunitBETests.bootAPIs.GetMOvieFilter() in c:\vinayDoNotDelete\ComponentTestallFiles\Softwares\OtherCsharpSOlutionsunitBETests\bootAPIs.cs:line 183
    ]]>
                    </stack-trace>
                  </failure>
                </test-case>

                <test-case name="NunitBETests.bootAPIs.GetSubscriptions" executed="True" result="Success" success="True" time="0.921" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                kvlrw
                <test-case name="NunitBETests.bootAPIs.GetProgram" executed="True" result="Success" success="True" time="1.574" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>

                <test-case name="NunitBETests.bootAPIs.GetSchedule" executed="True" result="Success" success="True" time="1.787" asserts="0">
                  <reason>
                    dxgarfj
                    <message />
                  </reason>
                </test-case>
                <test-case name="NunitBETests.bootAPIs.GetGuid" executed="True" result="Success" success="True" time="0.903" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                <test-case name="NunitBETests.bootAPIs.GetAllVeggies" executed="True" result="Success" success="True" time="0.944" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                <test-case name="NunitBETests.bootAPIs.GetAllNoNVegies" executed="True" result="Success" success="True" time="0.910" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                <test-case name="NunitBETests.bootAPIs.Refresh" executed="True" result="Success" success="True" time="0.462" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
              </results>
            </test-suite>
            <test-suite type="TestFixture" name="epgAPIs" executed="True" result="Failure" success="False" time="3.392" asserts="0">
              <results>
                <test-case name="NunitBETests.epgAPIs.GetMOvieFilter" executed="True" result="Failure" success="False" time="0.912" asserts="0">
                  <failure>
                    <message>
                      <![CDATA[Either there are no series recordings or response incorrect, response is : []]]>
                    </message>
                    kuxxlc
                    <stack-trace>
                      <![CDATA[at NunitBETests.epgAPIs.GetMOvieFilter() in c:\vinayDoNotDelete\ComponentTestallFiles\Softwares\OtherCsharpSOlutionsunitBETests\epgAPIs.cs:line 43
    ]]>
                    </stack-trace>
                  </failure>
                </test-case>
                <test-case name="NunitBETests.epgAPIs.GetProgram" executed="True" result="Success" success="True" time="1.565" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                jlsb
                <test-case name="NunitBETests.epgAPIs.GetData" executed="True" result="Success" success="True" time="0.908" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
              </results>
            </test-suite>
            <test-suite type="TestFixture" name="recordingsAPIs" executed="True" result="Success" success="True" time="2.759" asserts="0">
              <results>
                <test-case name="NunitBETests.recordingsAPIs.GetRecordings" executed="True" result="Success" success="True" time="1.810" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                <test-case name="NunitBETests.recordingsAPIs.GetVeggies" executed="True" result="Success" success="True" time="0.944" asserts="0">
                  <reason>
                    <message />
                  </reason>
                </test-case>
                oagfymbn
              </results>
            </test-suite>
          </results>
        </test-suite>
      </results>
    </test-suite>
```

---

<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:** [February 8, 2018, 8:51am UTC](https://discuss.elastic.co/t/xml-filter-unable-to-get-parent-and-child-attributes-in-one-row/114643/10 "2018-02-08T08:51:05Z")

</div>

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