- Mam ciąg zawierający dane XML.
- Muszę wstawić nowy węzeł jako dziecko określonego węzła (znam atrybut „id” rodzica)
- Podczas drukowania nowych danych xml nie można zmieniać znaczenia nowej wartości węzła.
kod:
String xmlSampleToEdit = """
<sample>
<items>
<one id="1">ONE</one>
<ten id="10">TEN</ten>
<twenty id="20"></twenty>
</items>
</sample>
"""
String newNodeValue = "twenty&one" //to keep unescaped !!!!
String newNodeName = "twentyone"
String parentNodeId = "20"
String ExpectedResult = """
<sample>
<items>
<one id="1">ONE</one>
<ten id="10">TEN</ten>
<twenty id="20">
<twentyone>twenty&one</twentyone>
</twenty>
</items>
</sample>
"""
Ten rodzaj węzłów będzie zawierał dane, które będą przetwarzane (nie w celu wyświetlania stron HTML), więc jeśli jest to przetwarzanie ze znakami ucieczki, zostanie przerwane.
Czy można wstawić nowy węzeł za pomocą StreamingMarkupBuilder i mkp.yieldUnescaped jeśli nie znam zawartości XML?
Jakieś inne rozwiązanie?
Odpowiedzi:
2 dla odpowiedzi № 1Oto kod do analizowania tekstu XML w Groovy jako węzeł drzewa.
def rootNode = new XmlParser().parseText(xmlSampleToEdit)
def node = rootNode.items."*".find { node->
node.name() == "twenty" && node.@id == "20"
}
Dalej jest kod, aby utworzyć nowy węzeł jako dziecko węzła o nazwie „dwadzieścia”:
def newNode = new groovy.util.Node( node, newNodeName )
newNode.setValue(newNodeValue)
Aby serializować XML z powrotem do tekstu, możesz użyć XmlNodePrinter lub XmlUtil.serialize ().
def xmlOutput = new StringWriter()
def xmlNodePrinter = new XmlNodePrinter(new PrintWriter(xmlOutput))
xmlNodePrinter.with {
preserveWhitespace = true
expandEmptyElements = true
quote = """ // Use single quote for attributes
}
xmlNodePrinter.print(rootNode)
def output = xmlOutput.toString()
println output
To wymyka zawartość tekstową „dwadzieścia i jeden”, ponieważ w przeciwnym razie nie byłby to prawidłowy dokument XML. Plik Specyfikacja XML stwierdza, że „znak ampersand (&) ilewy nawias ostry (<) nie może występować w ich dosłownej formie, z wyjątkiem sytuacji, gdy są używane jako ograniczniki znaczników ... jeśli są potrzebne gdzie indziej, muszą być poprzedzone ".
<sample>
<items>
<one id="1">ONE</one>
<ten id="10">TEN</ten>
<twenty id="20">
<twentyone>twenty&one</twentyone>
</twenty>
</items>
</sample>
Jeśli chcesz wydrukować go bez zmiany znaczenia, możesz po prostu zamienić „& amp” na „&” podczas drukowania.
println output.replaceAll("&", "&")
Dałoby to oczekiwany wynik:
<sample>
<items>
<one id="1">ONE</one>
<ten id="10">TEN</ten>
<twenty id="20">
<twentyone>twenty&one</twentyone>
</twenty>
</items>
</sample>
Aby uzyskać więcej informacji na temat przetwarzania XML w Groovy, zobacz http://www.groovy-lang.org/processing-xml.html