【问题标题】:Changing node name of xml-node with Java使用 Java 更改 xml-node 的节点名称
【发布时间】:2010-11-20 23:00:30
【问题描述】:

我有以下情况:我有一个 XML 文档,例如像这样

<someRootElement>
<tag1>
    <tag2 
        someKey=someValue
        someKey2=someValue2
    />
    <tag3/>
    <tag4
        newKey=newValue
        newKey2=newValue2
    />
</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) );

现在这确实在一定程度上起作用,正如我所提到的,我想我错过了添加子节点的部分,但我真正想知道的是,是否有一种非常短的方法来重命名无需复制所有内容并替换整个内容的父节点?

提前谢谢!!!

【问题讨论】:

    标签: java xml xmlnode


    【解决方案1】:

    使用Document.renameNode

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

    【讨论】:

      【解决方案2】:

      正如你得到的属性:

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

      并且您将这些属性添加到新元素中,

      您应该获取nodes.item(i) 的子节点并将它们设置在新节点中。

      您可以使用例如:

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

      【讨论】:

      • 也许我应该得到一个新的 Eclipse 或者它真的不知道 'addContent' :(
      • 抱歉,我使用的是 JDOM。通过 org.w3c:您可以使用 nodes.item(i).getChildNodes(); //返回子列表,然后使用 appendChild(Element) 循环它们; //附加每个孩子
      【解决方案3】:

      只需在要重命名的元素上调用setName("reallyCoolTag")。没有必要复制周围的孩子;元素的 name 属性是一个可变字段。

      【讨论】:

      • 我之前尝试过,但没有成功。也许我做错了?如果我要重命名的节点是“nodes.item(i)”并且根元素被称为 root,那么我到底是怎么做的呢?我已经尝试过:nodes.item(i).setName(newValue) ...但 Eclipse 希望我添加一个演员...
      • 它确实有效;它只是不会更改磁盘上的文件。您需要将文档保存在 RAM 中的某个位置才能看到效果。
      • 见上文,eclipse 要我添加演员表......我猜,该方法不应该那样工作......正如你在上面看到的那样,我正在保存我想要的更改制作:(
      • 对不起,我不是指根元素,而是要重命名的元素。真的没有必要复制孩子。只需搜索要重命名的元素并对其调用 setName() 即可。
      【解决方案4】:

      您可以为此使用 XSL 转换 (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:copy>
        </xsl:template>
        <xsl:template match="tag1"> <!-- switch the element name -->
          <xsl:element name="reallyCoolTag">
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
          </xsl:element>
        </xsl:template>
      </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));
      

      如果您想要 Document 作为输出,请参阅 DOMResult

      【讨论】:

      • 如果还需要运行java代码来运行样式表,最好只用java来解决问题。这样做可以限制所涉及的技术、磁盘访问和磁盘依赖性。当需要进行多项更改并且它们更加异构时,您可能更喜欢样式表。我建议使用 Document.renameNode
      【解决方案5】:

      您的 tag1 无效。它没有关闭>。属性也应该被引用。它应该是这样的,

      <someRootElement>
      <tag1>
          <tag2 
              someKey="someValue"
              someKey2="someValue2"
          />
          <tag3/>
          <tag4
              newKey="newValue"
              newKey2="newValue2"
          />
      </tag1>
      </someRootElement>
      

      尝试使用更正后的 XML。它应该可以工作。

      【讨论】:

      • 除此之外,建议的方法不起作用......我不得不遍历节点的子节点并添加 em ......但你是对的,我提出的方式无效它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多