Изменение node имени xml- node с помощью Java

У меня есть следующий сценарий: у меня есть XML-документ, например. как это

<somerootelement>
<tag1>
 <tag2 somekey="someValue" somekey2="someValue2">
 <tag3>
 </tag3></tag2></tag1>
</somerootelement>

Теперь я хочу, чтобы родительский tag1 назывался reallyCoolTag без потери дочерних узлов. Я пробовал следующее, но, к сожалению, он не работает, как мне бы хотелось (но я знаю, почему, b/c ему что-то не хватает, я думаю):

// the new element:
Element neu = doc.createElement( newValue );
// append it to the root:
root.appendChild( neu );
// get all the child nodes:
NamedNodeMap nnm = nodes.item(i).getAttributes();
for( int dg = 0; dg < nnm.getLength(); dg++ ){
 neu.setAttribute( nnm.item( dg ).getNodeName(),
 nnm.item( dg ).getNodeValue() );
}
//---------------------------------------------------------
// HERE I GUESS I AM MISSING THE PART WHERE THE CHILD NODES
// ARE BEING APPENDED TO THE NEW NODE?????
//---------------------------------------------------------
// nodes.item(i) := the old value (nodes := is a NodeList
root.replaceChild( neu, nodes.item(i));
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource( doc );
StreamResult result = new StreamResult( xml );
transformer.transform( source, result );
nodes.item( i ).getParentNode().removeChild( nodes.item(i) );

Теперь это работает в определенной степени, как я уже упоминал, я предполагаю, что мне не хватает части, в которой добавляются дочерние узлы, но то, что я действительно хотел знать, заключается в том, есть ли действительно короткий способ переименовать parent node без необходимости копировать все и заменить все это?

Thnx заранее!!!

5 ответов

Использование Document.renameNode:

NodeList nodes = document.getElementsByTagName("tag1");
for (Node eachNode: nodes) {
 document.renameNode(eachNode, null, "reallyCoolTag");
}


Для этого можно использовать XSL Transformation (XSLT):

<!--?xml version="1.0" encoding="UTF-8"?-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="xml" indent="yes">
 <xsl:template match="*"> <!-- match anything -->
 <xsl:copy>
 <xsl:copy-of select="@*">
 <xsl:apply-templates>
 </xsl:apply-templates></xsl:copy-of></xsl:copy>
 </xsl:template>
 <xsl:template match="tag1"> <!-- switch the element name -->
 <xsl:element name="reallyCoolTag">
 <xsl:copy-of select="@*">
 <xsl:apply-templates>
 </xsl:apply-templates></xsl:copy-of></xsl:element>
 </xsl:template>
</xsl:output></xsl:stylesheet>

Это можно использовать с пакетом javax.xml.transform (Java 1.4 и выше):

TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer(new StreamSource(
 new File("RenameTag.xslt")));
transformer
 .transform(new DOMSource(document), new StreamResult(System.out));

Смотрите DOMResult, если вы хотите Document в качестве вывода.


Просто позвоните setName("reallyCoolTag") на элемент (ы), который вы хотите переименовать. Нет необходимости копировать детей вокруг; атрибут name элемента является изменяемым полем.


Как вы получили атрибуты:

NamedNodeMap nnm = nodes.item(i).getAttributes();

и вы добавили эти атрибуты в новый элемент,

Вы должны получить дочерние элементы nodes.item(i) и установить их в новом node.

Вы можете использовать, например:

neu.addContent(nodes.item(i).getChildren());


Ваш тэг1 недействителен. У него нет закрытия > . Также должны указываться атрибуты. Это должно выглядеть так,

<somerootelement>
<tag1>
 <tag2 somekey="someValue" somekey2="someValue2">
 <tag3>
 </tag3></tag2></tag1>
</somerootelement>

Попробуйте исправить XML. Он должен работать.

licensed under cc by-sa 3.0 with attribution.