I would like to edit an existing XML file while preserving it's original layout. This includes new lines, comments etc. Editing is composed of finding elements inside the XML and modifying the text value.
My first try was using XMLParser with XmlUtil.serialize but that does not meet the requirement.
Anyone is aware of any alternative to XMLParser where edits are "in place" of the original XML string? If not, perhaps there is a library that performs search using XPath/GPath and just return the location of the find so I can do StringBuilder.replace.
EDIT:
For now I made this function, to find string indexes of XML node (that I can find using xpath) then I am doing replace on the indexes. Works fine for simple nodes <node>value</node>:
def find_location_by_node(xmlString, root_xml, node)
{
current_index = 0;
for(current_node in root_xml.depthFirst())
{
node_name = current_node.name().getLocalPart()
current_index = xmlString.indexOf('<' + node_name, current_index);
if(current_node == node)
{
end_tag = '</' + node_name + '>';
end_tag_index = xmlString.indexOf(end_tag, current_index) + end_tag.length();
return [current_index, end_tag_index];
}
}
return -1;
}
You could update your XML with DOMCategory. DOM will keep your original layout.
import groovy.xml.DOMBuilder
def input = '''
<shopping>
<category type="groceries">
<item>Chocolate</item>
<item>Coffee</item>
</category>
<category type="supplies">
<item>Paper</item>
<item quantity="4">Pens</item>
</category>
<category type="present">
<item when="Aug 10">Kathryn's Birthday</item>
<item>Chocolate</item>
</category>
</shopping>
'''
def doc = DOMBuilder.parse(new StringReader(input))
def root = doc.documentElement
use(groovy.xml.dom.DOMCategory) {
def chocolate = root.depthFirst().grep{it.text() == "Chocolate"}
chocolate*.value = "Nutella"
}
def result = groovy.xml.dom.DOMUtil.serialize(root)
println result
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With