Я использую groovy для анализа XML-файла с использованием XmlParser. Чтобы избежать обработки префиксов пространства имен, я использовал метод xmlRoot. '**'. FindAll () для поиска некоторых узлов. Пример кода показывает, как он работает правильно, пока я просто не прочитал узлы, потому что каждый элемент, передаваемый замыканию, является объектом Node. Но когда я изменяю содержимое узла (в данном случае просто текст узла), следующий вызов findAll не выполняет итерации для объектов Node. Для каждого символа, который я вставляю в текст, объект String передается в замыкание. Я решил это, проверив тип с instanceof, но похоже, что это ошибка.
Я что-то не так делаю или это ошибка?
class XmlParserTest {
static final String XML_SAMPLE = """
<ns0:root xmlns:ns0="mycompany.com">
<ns0:firstParent>
<ns0:item1>uppercase_me!</ns0:item1>
</ns0:firstParent>
<ns0:secondParent>
<ns0:item2>uppercase_me_too!/ns0:item2>
</ns0:secondParent>
</ns0:root>
"""
static void main(String[] args) {
def xmlRoot = new XmlParser(false, false).parseText(XML_SAMPLE)
//******* find item1 and capitalize its text ********
def nds1 = xmlRoot.'**'.findAll {
it.name().equals("ns0:item1")
}
Node nd1 = nds1[0]
//This changes the text of the node, but something strange happens to the node tree
nd1.setValue(nd1.value().toString().toUpperCase())
//The same problem happens using replaceNode() instead of setValue()
//Node newNode = new Node(nd1.parent(), nd1.name(), nd1.value().toString().toUpperCase())
//nd1.replaceNode(newNode)
//******* find item2 and capitalize its text ********
def nds2 = xmlRoot.'**'.findAll {
//for each character in the string "uppercase me!" a String is passed instead of Node
//As String doesn't have a name method, an exception is raised
it.name().equals("ns0:item2")
//using instanceof fixes the problem, at least for this case
it instanceof Node && it.name().equals("ns0:item2")
}
Node nd2 = nds2[0]
nd2.setValue(nd2.value().toString().toUpperCase())
assert nd1.value().toString() == nd1.value().toString().toUpperCase()
assert nd2.value().toString() == nd2.value().toString().toUpperCase()
}
}