/ / Edycja ciągu XML za pomocą Groovy - xml, groovy

Edytowanie łańcucha XML za pomocą Groovy - xml, groovy

  • 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 № 1

Oto 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&amp;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("&amp;", "&")

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