RuntimeError: attempted adding second root element to document

Hi,
I am facing below error while Logstash is parsing my xml file which was extracted for the given pattern. DUe to this error , I am not able to create visualisation as well as the required fields in Visualisation is not visible at all. Kindly help me resolving this issue.

Below is the grok code in my .conf file.

input { file {
path => "path/LogisticProcesses-*"
start_position => "beginning"
type => "xml"
codec => multiline {
          pattern => "^%{YEAR} "
          negate => true
	  what => "previous"
 	  auto_flush_interval => 1
                  }

 }}

filter {

grok {   match => { "message" => ["%{YEAR:Year} %{MONTH:Month} %{MONTHDAY:Day} %{INT:Hour}:%{INT:Minutes}:%{INT:Seconds}:%{INT:MS} %{WORD:Zone} +%{INT:ZoneNum} BW.%{NOTSPACE:Adapter} %{NOTSPACE:Role} %{NOTSPACE:Category} %{NOTSPACE:MsgCode} MSGID=(?<MSGID>[[:ascii:]]{27}) Received synchronous RV request %{GREEDYDATA:Rest}","%{YEAR:Year} %{MONTH:Month} %{MONTHDAY:Day} %{INT:Hour}:%{INT:Minutes}:%{INT:Seconds}:%{INT:MS} %{WORD:Zone} +%{INT:ZoneNum} BW.%{NOTSPACE:Adapter} %{NOTSPACE:Role} %{NOTSPACE:Category} %{NOTSPACE:MsgCode} MSGID=(?<MSGID>[[:ascii:]]{27}) %{GREEDYDATA:Rest1}"] }}

#grok {   match => { "message" => "%{YEAR:Year} %{MONTH:Month} %{MONTHDAY:Day} %{INT:Hour}:%{INT:Minutes}:%{INT:Seconds}:%{INT:MS} %{WORD:Zone} +%{INT:ZoneNum} BW.%{NOTSPACE:Adapter} %{NOTSPACE:Role} %{NOTSPACE:Category} %{NOTSPACE:MsgCode} MSGID=(?<MSGID>[[:ascii:]]{27}) %{GREEDYDATA:Rest}" } }

if "_grokparsefailure" in [tags] {
      drop { }
    }

mutate {
      remove_field => ["Zone", "ZoneNum", "MsgCode", "Job"]
    }


xml { source => "Rest" target => "lpXML" store_xml => true }

Below is the error I get:

:exception=>#<REXML::ParseException: #<RuntimeError: attempted adding second root element to document>
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/document.rb:96:in `add'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/element.rb:904:in `add'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/child.rb:22:in `initialize'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/parent.rb:14:in `initialize'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/element.rb:60:in `initialize'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/element.rb:902:in `add'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/element.rb:298:in `add_element'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/document.rb:103:in `add_element'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/parsers/treeparser.rb:34:in `parse'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/document.rb:288:in `build'
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/rexml/document.rb:45:in `initialize'
/afs1/tibco/ELK/logstash-7.3.1/vendor/bundle/jruby/2.5.0/gems/xml-simple-1.1.5/lib/xmlsimple.rb:971:in `parse'
/afs1/tibco/ELK/logstash-7.3.1/vendor/bundle/jruby/2.5.0/gems/xml-simple-1.1.5/lib/xmlsimple.rb:164:in `xml_in'
/afs1/tibco/ELK/logstash-7.3.1/vendor/bundle/jruby/2.5.0/gems/xml-simple-1.1.5/lib/xmlsimple.rb:203:in `xml_in'
/afs1/tibco/ELK/logstash-7.3.1/vendor/bundle/jruby/2.5.0/gems/logstash-filter-xml-4.0.7/lib/logstash/filters/xml.rb:185:in `filter'
/afs1/tibco/ELK/logstash-7.3.1/logstash-core/lib/logstash/filters/base.rb:143:in `do_filter'
/afs1/tibco/ELK/logstash-7.3.1/logstash-core/lib/logstash/filters/base.rb:162:in `block in multi_filter'
org/jruby/RubyArray.java:1792:in `each'
/afs1/tibco/ELK/logstash-7.3.1/logstash-core/lib/logstash/filters/base.rb:159:in `multi_filter'
org/logstash/config/ir/compiler/AbstractFilterDelegatorExt.java:115:in `multi_filter'
/afs1/tibco/ELK/logstash-7.3.1/logstash-core/lib/logstash/java_pipeline.rb:239:in `block in start_workers'
...
attempted adding second root element to document

That is telling your XML has two root elements, like this

<foo></foo> <foo></foo>

You can either change your multiline filter to capture a single element, or wrap them and then split them.

mutate { gsub => [ "message", "^", "<a>", "message", "$", "</a>" ] }
xml { ... }
split { field => "a" }

Hi Badger,

Below is the xml I wanted to extract and send to KIBANA but I get second root element error as mentioned earlier. I did not understand how to split it for this type of XML here.
Please refer my .conf file I shared in my above message.

XML Message I am trying to pull from my logs , parse logstash and project on index KIBANA.

2020 Sep 18 05:01:23:788 GMT +0200 BW.LogisticProcesses-2-LogisticProcesses-040101-2 Activity [Transport] EAI-04057 MSGID=VBEldVUWbmX4ckM5MA-7f7XU6W2 Sending JMS notification
Queue: ACC.FIXED.QUEUE.NAME
Header:
<?xml version="1.0" encoding="UTF-8"?>
<JMS/>
Body:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:LogisticActivity.1 xmlns:ns0="http://xmlns.kpn.com/fixed/">
    <ns1:CMH xmlns:ns1="http://xmlns.kpn.com/common/cdm/Base.xsd">
        
    </ns1:CMH>
	
    <ns1:BODY xmlns:ns1="http://xmlns.kpn.com/EAI/fixed/">
        
    </ns1:BODY>
</ns0:LogisticActivity.1>

OK, so this is the first element

and this is the second.

If you only want the second you could

mutate { add_field => { "[@metadata][xml]" => "%{message}" } }
mutate { gsub => [ "[@metadata][xml]", ".*Body:", "" ] }
xml { source => "[@metadata][xml]" ... }

I will try these changes and will let you know the results.