1

I am trying to insert a node into an existing XML document. I use groovy and ANT for that.

So does my XML look like:

<root>
 <node1 db="a" 
   user="test"/>
</root>

Within this XML file I have a groovy section that looks that way:

My groovy script, embedded in the ANT xml file.

<target name="some-target">
 <script language="groovy">
 def fragment = '''&lt;root&gt;
 &lt;node1 db=&quot;a&quot; 
   user=&quot;test&quot;/&gt;
&lt;/root&gt;''';

def parser = new XmlParser();
xml.appendNode{fragment};

def xmlOutput = new StringWriter();
def xmlNodePrinter = new XmlNodePrinter(new PrintWriter(xmlOutput));      
xmlNodePrinter.print(xml);

Now, I just want to add a second node, but I do not how to achieve that?

If I add now a second node I always get the following output in the result:

<root>
 <node1 db="a" 
   user="test"/>
   <Script1$_run_closure2@451001e5/>
</root>

Thank you for your help in advance!

Bernd
  • 593
  • 2
  • 8
  • 31

1 Answers1

1

No need to use the Ant task, you can do this in plain Groovy:

Assuming you have a file variable which points to your existing XML

def fileText = new File('/tmp/test.xml')

Then, you can do:

import groovy.xml.*

def fileText = new File('/tmp/test.xml')

def parser = new XmlParser()

def xml = parser.parse('/tmp/test.xml')

// Add a new node
xml.append(parser.parseText('<node2 db="c" user="test2"/>'))

// Write it out over the top of the original file
def xmlOutput = new StringWriter()
def xmlNodePrinter = new XmlNodePrinter(new PrintWriter(xmlOutput))
xmlNodePrinter.print(xml)
fileText.text = xmlOutput.toString()

Edit

Right, here's 2 methods to append a node. I've put xmltask.jar in the same folder as the build. The first target uses xmltask, the second uses groovy.

I've also added test.xml to the same directory, and this is what is read-in, appended to and written out

<project name="Xml Foozling" basedir=".">

  <path id="runtime.path">
    <pathelement location="xmltask.jar"/>
  </path>

  <taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpathref="runtime.path"/>

  <target name="insert-node-with-xml-task">
    <xmltask source="test.xml" dest="output-task.xml">
        <insert path="/root">
          <![CDATA[
          <node1 db="new"  user="hooray"/>
          ]]>
        </insert>
    </xmltask>
  </target>

  <target name="insert-node-with-groovy">
    <script language="groovy">
      <![CDATA[
      import groovy.xml.*

      new XmlParser().with { parser ->
        parser.parse('test.xml').with { xml ->
          xml.append(parser.parseText('<node2 db="new" user="hooray"/>'))
          new File('output-script.xml').withWriter { out ->
            new XmlNodePrinter(new PrintWriter(out)).print(xml)
          }
        }
      }
      ]]>
    </script>
  </target>

</project>

Fingers crossed

tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • Thanks for your help! Well, I must do it with ANT, do have any idea how to accomplish that? – Bernd Mar 19 '18 at 14:14
  • I'll have a think – tim_yates Mar 19 '18 at 14:53
  • Can you use xmltask? https://stackoverflow.com/questions/22514657/insert-xml-element-in-xml-document-using-ant – tim_yates Mar 19 '18 at 14:54
  • Well, I forgot to say that I had to escape the additional node in my script. If I use your groovy script now, I always get the following string into my XML: - but not the new node, I think it has something to do with the escaping? – Bernd Mar 19 '18 at 15:10
  • Why did you have to escape it? – tim_yates Mar 19 '18 at 17:17
  • grovvy is embedded in an xml file; this xml file has targets that I call. Furthermore, I use an XSD file to check the XML.As soon as I do not escape it, I always get an error like: script doesn't support the nested element. – Bernd Mar 19 '18 at 18:03
  • Can you wrap it in a CDATA block instead of escaping it? – tim_yates Mar 19 '18 at 18:29
  • Hm, I have to lok it up. Have not ever worked with CDATA - blocks. – Bernd Mar 19 '18 at 18:45
  • This might help: https://stackoverflow.com/questions/2784183/what-does-cdata-in-xml-mean – tim_yates Mar 19 '18 at 18:46
  • Thanks, then I will try it this way, too. Sadly, that escaping the XML part reduced the errors but produced not what I expected. Would have solved quickly my problem but what I always get is: -- seems to be the memory address or wrong interpretation of my escaped string? – Bernd Mar 19 '18 at 18:55
  • I tried it with CDATA but that also did not help since the output is always a valid XML with this before the closing root node: - I think I have to find a way to reverse the escaping string. It could be everything done in groovy, so that would not be a problem although I said before that it has to be done in ANT. – Bernd Mar 20 '18 at 07:45
  • Maybe the easiest solution would be to delete the root node at the end of the file and past from an extra file the missing node into this file? – Bernd Mar 20 '18 at 08:06
  • Can you change the question so it shows a complete example that I can run and see the problem? I'm a bit lost at the moment ☹️ – tim_yates Mar 20 '18 at 08:11
  • Added to the answer... Fingers crossed, not used Ant for about 6 years but it seems to work ;-) – tim_yates Mar 20 '18 at 09:51
  • Hi, it works great. I used the xmltask variant! How can I thank you? Thousand thanks!!!!! – Bernd Mar 20 '18 at 14:05
  • Yay! No worries :-) Don't forget to help someone when they're stuck in the future :-) – tim_yates Mar 20 '18 at 14:32
  • Sure, never had the idea of not helping someone! Thank you very much for your great help, again!!! – Bernd Mar 20 '18 at 19:01