For the sake of completeness: If you need multiple attributes from the parent item and the reports, it might be easier to just split your XML in multiple steps instead of trying to access the data directly.
filter {
xml {
store_xml => false
source => "message"
xpath => [
"//ReportHost", "hostdata"
]
}
split {
field => "hostdata"
}
xml {
store_xml => false
source => "hostdata"
xpath => [
"//ReportItem", "reportitem",
"//tag[@name='host-ip']/text()", "ip"
]
}
split {
field => "reportitem"
}
xml {
target => "reportdata"
source => "reportitem"
}
mutate {
remove_field => ["message", "hostdata", "reportitem"]
rename => {"[ip][0]" => "[reportdata][ip]"}
}
}
{
"ip" => [],
"host" => "elasticsearch-vm",
"@version" => "1",
"reportdata" => {
"svc_name" => "general",
"ip" => "1.111.11.114",
"description" => [
[0] "teeext"
],
"port" => "22",
"protocol" => "tcp",
"severity" => "8",
"fname" => [
[0] "teeext"
]
},
"@timestamp" => 2018-10-26T13:01:59.450Z
}
(Alternative with less XML parsing:)
filter {
xml {
target => doc
source => "message"
}
split {
field => "[doc][ReportHost]"
}
split {
field => "[doc][ReportHost][ReportItem]"
}
mutate {
remove_field => ["message"]
}
}
{
"host" => "elasticsearch-vm",
"@version" => "1",
"@timestamp" => 2018-10-26T13:19:48.436Z,
"doc" => {
"ReportHost" => {
"ReportItem" => {
"fname" => [
[0] "teeext"
],
"severity" => "8",
"description" => [
[0] "teeext"
],
"port" => "22",
"protocol" => "tcp",
"svc_name" => "general"
},
"name" => "1.111.11.114",
"HostProperties" => [
[0] {
"tag" => [
[0] {
"name" => "host-ip",
"content" => "1.111.11.114"
}
]
}
]
}
}
}
(In both versions you'll have some cleanup to do to get a nice finished structure )