有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

基于Java中的XML值重新创建XML

我有一个动态XML,需要根据其XML的值进行转换。需要删除属性为type="newNode"的组节点,因为它们已派生

我尝试了以下方法:

  1. 基于XML创建新节点并删除不必要的节点,但我在使用doc.removeChild(node)时遇到了一个问题

    Exception in thread "main" org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist.

    NodeList nodeList = doc.getElementsByTagName(NODE_MAPPINGS_NODE);
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node nodeToBeRemoved = nodeList.item(i);
        if (nodeToBeRemoved.getNodeType() == Node.ELEMENT_NODE) {
            doc.getDocumentElement().removeChild(nodeToBeRemoved);
        }
    }
    
  2. 基于原始文档创建了一个新文档,但我遇到一个错误

    Exception in thread "main" org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.

    NodeList nodeList = doc.getElementsByTagName(NODE_MAPPINGS_NODE);
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            if(!node.hasAttributes()) {
                Element elem = newDoc.createElement(node.getNodeName());
                newDoc.appendChild(elem);
            }
        }
    }
    

下面是我试图解析的示例XML:

<root>
    <input>
        <nodeMappings type="newNode">
            <name>declarationType</name>
            <type>derived</type>
            <derivedValue>X</derivedValue>
        </nodeMappings>
        <nodeMappings type="newNode">
            <name>identificationNumber</name>
            <type>derived</type>
            <derivedValue>5000000612</derivedValue>
        </nodeMappings>
        <characteristicsOfTaxPayer>
            <nodeMappings type="newNode">
                <name>collectivePerson</name>
                <type>derived</type>
                <derivedValue>X</derivedValue>
            </nodeMappings>
        </characteristicsOfTaxPayer>
        <listTest>
            <nodeMappings type="newNode">
                <name>primaryKey</name>
                <type>derived</type>
                <derivedValue>1</derivedValue>
            </nodeMappings>
            <nodeMappings type="newNode">
                <name>value</name>
                <type>derived</type>
                <derivedValue>test1</derivedValue>
            </nodeMappings>
        </listTest>
        <listTest>
            <nodeMappings type="newNode">
                <name>primaryKey</name>
                <type>derived</type>
                <derivedValue>2</derivedValue>
            </nodeMappings>
            <nodeMappings type="newNode">
                <name>value</name>
                <type>derived</type>
                <derivedValue>test2</derivedValue>
            </nodeMappings>
        </listTest>
    </input>
</root>

处理后,应如下所示:

<root>
    <input>
        <declarationType>X</declarationType>
        <identificationNumber>5000000612</identificationNumber>
        <characteristicsOfTaxPayer>
            <collectivePerson>X</collectivePerson>
        </characteristicsOfTaxPayer>
        <listTest>
            <primaryKey>1</primaryKey>
            <primaryKey>test1</primaryKey>
        </listTest>
        <listTest>
            <primaryKey>2</primaryKey>
            <primaryKey>test2</primaryKey>
        </listTest>
    </input>
</root>

有更好的方法吗


共 (1) 个答案

  1. # 1 楼答案

    完整的工作可以用一个简单的xslt来完成

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
      
      <xsl:output method="xml" encoding="utf-8" indent="yes"/>
      
      <!  Identity template : copy all text nodes, elements and attributes  >   
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
      
      <xsl:template match="nodeMappings[@type='newNode']" >
        <xsl:element name="{name/text()}"><xsl:value-of select="derivedValue/text()"/></xsl:element>
      </xsl:template>
    
    </xsl:stylesheet>
    

    如果惯例中有一个例外是正确的:文本值name元素成为新创建的元素,即<name>value</name>变成<primaryKey/>,xslt将是:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
      
      <xsl:output method="xml" encoding="utf-8" indent="yes"/>
      
      <!  Identity template : copy all text nodes, elements and attributes  >   
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
      
      <xsl:template match="nodeMappings[@type='newNode']" >
        <xsl:element name="{name/text()}"><xsl:value-of select="derivedValue/text()"/></xsl:element>
      </xsl:template>
    
      <xsl:template match="nodeMappings[@type='newNode'][name='value']" >
        <primaryKey><xsl:value-of select="derivedValue/text()"/></primaryKey>
      </xsl:template>
    
    </xsl:stylesheet>