Groovy更新XML元素值时如何保留原格式对齐?
Let's tackle this problem step by step. You've got the core functionality working (updating the State value when Name is "Super1"), but the unwanted extra spaces around element text and messed-up formatting are frustrating. Here's why it's happening and how to fix it:
Why the extra spaces and formatting issues?
The XmlParser you're using parses every piece of the XML, including whitespace like indentation spaces and newlines as separate text nodes. When you use XmlNodePrinter without custom configuration, it adds its own indentation and spacing, which leads to those extra spaces around your element text and disrupts the original formatting. Also, note your original code had a node path mismatch (Plugins.Plugin instead of Parent.Test for your XML structure) — that's fixed in the solutions below.
Solution 1: Use XmlSlurper + XmlUtil (cleanest approach)
XmlSlurper ignores insignificant whitespace by default, which avoids the extra space problem entirely, and XmlUtil.serialize() generates clean, properly formatted XML that matches your desired output. Here's the adjusted code:
def xmlfile = new File("D:/z/Test.xml") def rootNode = new XmlSlurper().parse(xmlfile) // Locate all Test nodes where Name equals "Super1" and update State rootNode.Parent.Test.findAll { it.Name.text() == "Super1" }.each { testNode -> testNode.State = "Enabled" } // Serialize the updated XML def updatedXml = XmlUtil.serialize(rootNode) // Replace the default XML declaration to match your original file's format updatedXml = updatedXml.replaceFirst('<?xml version="1.0" encoding="UTF-8"?>\n', '<?xml version="1.0" standalone="yes"?>\r\n') // Write the updated content back to the file xmlfile.write(updatedXml) println("Updated Ec2ConfigService Test xml")
Key details:
XmlSlurperhandles whitespace intelligently, so your element text won't get extra paddingXmlUtil.serialize()produces well-structured XML that preserves the original indentation style- Fixed the node path to align with your actual XML structure
Solution 2: Configure XmlNodePrinter to preserve whitespace
If you prefer sticking with XmlParser, you can adjust the XmlNodePrinter settings to retain the original whitespace and avoid adding extra spaces:
def xmlfile = new File("D:/z/Test.xml") def people = new XmlParser().parse(xmlfile) // Find the correct Test nodes, using trim() to handle any accidental whitespace in Name people.Parent.Test.findAll { p -> if(p.Name.text().trim() == "Super1") { p.State[0].value = "Enabled" println(p.State.text()) } } def stringWriter = new StringWriter() // Configure printer to preserve original whitespace instead of adding its own def printer = new XmlNodePrinter(new PrintWriter(stringWriter)) printer.preserveWhitespace = true printer.print(people) def newXml = stringWriter.toString() xmlfile.write("<?xml version=\"1.0\" standalone=\"yes\"?>\r\n"+newXml) println("Updated Ec2ConfigService Test xml")
Key details:
preserveWhitespace = truetells the printer to respect the original XML's spacing instead of overriding it- Using
trim()onp.Name.text()ensures you match "Super1" even if there's accidental whitespace in the original XML - Fixed the node path to match your actual XML hierarchy
Either of these approaches will give you the desired output without extra spaces or disrupted formatting.
内容的提问来源于stack exchange,提问作者bikram kumar Nayak

