0

Scenario

Need to update some attributes in an existing XML-file. The file contains a XSL processing instruction, so when the XML is parsed and updated I need to add the instruction before writing it to a file again. Problem is - whatever I do - I'm not able to insert the processing instruction

Based on the Java-example found at rgagnon.com I have created the code below

Example code ##

import groovy.xml.*

def xml = '''|<something>
            |  <Settings>
            |  </Settings>
            |</something>'''.stripMargin()

def document = DOMBuilder.parse( new StringReader( xml ) )
def pi = document.createProcessingInstruction('xml-stylesheet', 'type="text/xsl"    href="Bp8DefaultView.xsl"');
document.insertBefore(pi, document.documentElement) 

println document.documentElement

Creates output

<?xml version="1.0" encoding="UTF-8"?>
<something>
  <Settings>
  </Settings>
</something>

What I want

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Bp8DefaultView.xsl"?>
<something>
  <Settings>
  </Settings>
</something>
rhellem
  • 769
  • 1
  • 11
  • 26

1 Answers1

1

You're inserting the PI before the documentElement, but then passing only the element to println. Does it work if you print the whole document?

Failing that, the "official" way to output a DOM document is to use LSSerializer

def ser = document.implementation.createLSSerializer()
new File("output.xml").withOutputStream { o ->
  def lso = document.implementation.createLSOutput()
  lso.byteStream = o
  ser.write(document, lso)
}
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • According to the JavaDoc, the documentElement-method "_This is a convenience attribute that allows direct access to the child node that is the document element of the document._". So I see your point, but I'm not able to find any other method, not in Node either, that should solve this. Using [StreamingMarkupBuilder](http://www.ibm.com/developerworks/java/library/j-pg05199/#N101D9) I've been able to output the XSL as well, but I've not been able to adopt the same using the code above. Tried to figure out if I could read the content of the file and use StreamingMarkupBuilder, but no luck so far – rhellem Dec 08 '12 at 21:41
  • 1
    @rhellem the `document` node has a list of child nodes, the PI is one of these, the `documentElement` is another. I'm suggesting you try `println document` instead of `println document.documentElement` to see if that includes the PI as well. – Ian Roberts Dec 08 '12 at 21:49
  • Notice that the processing instruction is added to the end of the document. [Node order should not be important](http://francisoud.blogspot.no/2008/09/is-node-order-important-in-xml.html), but still it might be confusing, but then I found [this Q&A here at Stackoverflow](http://stackoverflow.com/questions/7980033/serialize-xml-processing-instruction-before-root-element) solving that issue as well. So now problem solved, so thanks! – rhellem Dec 09 '12 at 19:10
  • 1
    Ahh, and just noticed now that when using the code as you suggest - I do not need to add the processing instruction, since it is found while reading the original file - together with comments all other stuff. Thanks a bunch once more! – rhellem Dec 09 '12 at 19:31