[groovy-user] How to append a XML subtree to a given XML?

2,824 views
Skip to first unread message

BUSSCHAERT Frédéric

unread,
Apr 15, 2013, 8:52:35 AM4/15/13
to us...@groovy.codehaus.org

Could you tell me what is the easiest way to append a XML subtree to a given XML, at a given place?

 

Example :

 

def xml1 = ‘’’

<root>

  <node1>

    <subnode1_1>xyz</subnode1_1>

    <subnode1_2></subnode1_2>

  </node1>

  <node2>

    <subnode2_1>xyz</subnode2_1>

  </node2>

</root>

‘’’

 

def xml2 = ‘’’

<node3>

  <subnode3_1>sn31</subnode3_1>

  <subnode3_2>sn32</subnode3_2>

</node3>

‘’’

 

Result :

 

def xml3 = ‘’’

<root>

  <node1>

    <subnode1_1>xyz</subnode1_1>

    <subnode1_2></subnode1_2>

  </node1>

  <node2>

    <subnode2_1>xyz</subnode2_1>

  </node2>

  <node3>

    <subnode3_1>sn31</subnode3_1>

    <subnode3_2>sn32</subnode3_2>

  </node3>

</root>

‘’’

 

Should I use XmlParser, XmlSlurper, MarkupBuilder, DOMBuilder…? and how?

 

Thank you,

 

Frédéric.

 

Guillaume Laforge

unread,
Apr 15, 2013, 9:00:18 AM4/15/13
to Groovy User
Hi Frédéric,

First of all, did you have a look at our documentation on how to deal with XML?

There are a few options listed down the page regarding updates that might be of help.

Guillaume
--
Guillaume Laforge
Groovy Project Manager
Head of Groovy Development at SpringSource
http://www.springsource.com/g2one

Alex Anderson

unread,
Apr 15, 2013, 10:12:13 AM4/15/13
to us...@groovy.codehaus.org
Personally I found the XML documentation unclear.

Frédéric, try something like:

import groovy.xml.StreamingMarkupBuilder
def x1 = new XmlParser().parseText(xml1)
def x2 = new XmlParser().parseText(xml2)
x1.root[0].appendNode(x2)
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(x1)
def xml3 = writer.toString()

N.B. I'd be surprised if there isn't a much simpler way of doing
this., but I've yet to discover it.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Mario Garcia

unread,
Apr 15, 2013, 11:18:39 AM4/15/13
to us...@groovy.codehaus.org
Well if you're just mixin strings you can use XmlStringTemplateEngine:

import groovy.text.*

def theOtherStringXml = '''

<node3>

  <subnode3_1>sn31</subnode3_1>

  <subnode3_2>sn32</subnode3_2>

</node3>

'''


def xml1 = '''

<root>

<node1>

    <subnode1_1>xyz</subnode1_1>

    <subnode1_2></subnode1_2>

  </node1>

  <node2>

    <subnode2_1>xyz</subnode2_1>

  </node2>


  ${childNode}

</root>

'''

def mixedXml = new XmlTemplateEngine().createTemplate(xml1).make([childNode: theOtherStringXml]).toString()

def parsedXml = new XmlSlurper().parseText(mixedXml)

I did a couple of entries earlier this month because I wanted to know a little bit more about processing xml with groovy. Here I leave you the entry. One of them is focused on XmlTemplateEngine.:

http://desmontandojava.blogspot.ie/2013/04/groovy-xml-series-index.html

Anyway I don't think I'm gonna clarify much more than the Groovy documentation. Anyway I hope it helps.




2013/4/15 Alex Anderson <alexanderande...@gmail.com>

BUSSCHAERT Frédéric

unread,
Apr 16, 2013, 5:03:17 AM4/16/13
to us...@groovy.codehaus.org
Dear Alex,

I tried your code but I got an error message:
Java.lang.NullPointerException: Cannot invoke method appendNode() on null object - error at line: 39

This is the code I ran in SoapUI 4.5.1, line 39 is where appendNode() is used:

def xml1 = '''
<root>
<node1>
<subnode1_1>xyz</subnode1_1>
<subnode1_2></subnode1_2>
</node1>
<node2>
<subnode2_1>xyz</subnode2_1>
</node2>
</root>
'''

def xml2 = '''
<node3>
<subnode3_1>sn31</subnode3_1>
<subnode3_2>sn32</subnode3_2>
</node3>
'''

def xml_result = '''
<root>
<node1>
<subnode1_1>xyz</subnode1_1>
<subnode1_2></subnode1_2>
</node1>
<node2>
<subnode2_1>xyz</subnode2_1>
</node2>
<node3>
<subnode3_1>sn31</subnode3_1>
<subnode3_2>sn32</subnode3_2>
</node3>
</root>
'''

import groovy.xml.StreamingMarkupBuilder
def x1 = new XmlParser().parseText(xml1)
def x2 = new XmlParser().parseText(xml2)
x1.root[0].appendNode(x2)
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(x1)
def xml3 = writer.toString()


I tried also this: x1.root.appendNode(x2) => other error message
And this: x1.appendNode(x2) => node3 is appended but empty!

Did I do something wrong?

Regards,

Frédéric.

-----Message d'origine-----
De : Alex Anderson [mailto:alexanderande...@gmail.com]
Envoyé : lundi 15 avril 2013 16:12
À : us...@groovy.codehaus.org
Objet : Re: [groovy-user] How to append a XML subtree to a given XML?
>> Should I use XmlParser, XmlSlurper, MarkupBuilder, DOMBuilder...? and how?

BUSSCHAERT Frédéric

unread,
Apr 16, 2013, 5:14:17 AM4/16/13
to us...@groovy.codehaus.org

Hi Guillaume,

 

Yes I looked at the documentation, which gives good examples for parsing or creating an XML from scratch, for modifying, removing or adding a node in a XML tree, but does not explain how to add a whole XML subtree in another XML tree.

 

Moreover, I have to work with a SOAP XML, so to deal with several namespaces, and in the sopaUI tool, so I need to be able to get/set XML trees from soapUI requests.

 

I finally found a solution, but it is requires a lot of code and is not really “groovy-like”:

 

def grUtils = new com.eviware.soapui.support.GroovyUtils(context)

def requestHolder = grUtils.getXmlHolder("myRequest#Request")

def inscriptionNode = requestHolder.getDomNode("//*:Envelope/*:Body/*:InscriptionRequete/*:Inscription")

def namespace = inscriptionNode.getNamespaceURI()

def requestDoc = inscriptionNode.getOwnerDocument()

def verificationNode = requestHolder.getDomNode("//*:Envelope/*:Body/*:InscriptionRequete/*:Inscription/*:Verification")

 

def specificiteNode = requestDoc.createElementNS(namespace, 'Specificite')

inscriptionNode.insertBefore(specificiteNode, verificationNode)

 

def specCoefComptageNode = requestDoc.createElementNS(namespace, 'CoefficientComptage')

specificiteNode.appendChild(specCoefComptageNode)

def specCoefComptageText = requestDoc.createTextNode('1,0')

specCoefComptageNode.appendChild(specCoefComptageText)

 

def specEnfantPlaceNode = requestDoc.createElementNS(namespace, 'EnfantPlace')

specificiteNode.appendChild(specEnfantPlaceNode)

def specEnfantPlaceText = requestDoc.createTextNode('N')

specEnfantPlaceNode.appendChild(specEnfantPlaceText)

 

(…)

 

def specAbsence9DJNode = requestDoc.createElementNS(namespace, 'Absence9DemiJours')

specificiteNode.appendChild(specAbsence9DJNode)

def specAbsence9DJIndicateurNode = requestDoc.createElementNS(namespace, 'Indicateur')

specAbsence9DJNode.appendChild(specAbsence9DJIndicateurNode)

def specAbsence9DJIndicateurText = requestDoc.createTextNode('O')

specAbsence9DJIndicateurNode.appendChild(specAbsence9DJIndicateurText)

def specAbsence9DJDateNode = requestDoc.createElementNS(namespace, 'Date')

specAbsence9DJNode.appendChild(specAbsence9DJDateNode)

def specAbsence9DJDateText = requestDoc.createTextNode('2012-09-28')

specAbsence9DJDateNode.appendChild(specAbsence9DJDateText)

 

requestHolder.updateProperty(true)

 


De : Guillaume Laforge [mailto:glaf...@codehaus.org]
Envoyé : lundi 15 avril 2013 15:00
À : Groovy User
Objet : Re: [groovy-user] How to append a XML subtree to a given XML?

Reply all
Reply to author
Forward
0 new messages