Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 复制XML并重命名其某些节点和嵌套节点_Xslt_Xpath - Fatal编程技术网

Xslt 复制XML并重命名其某些节点和嵌套节点

Xslt 复制XML并重命名其某些节点和嵌套节点,xslt,xpath,Xslt,Xpath,我需要将所有内容复制到新的XML中,除了一些需要重命名的元素 所有属于“node1”子节点的“child”节点需要重命名为“children”,属于“node2”子节点的“child”节点需要重命名为“kid” 完美的解决方案将使用 match="/root/node1/descendant::child" 但正如我在迈克尔·凯对这个话题的回应中所发现的那样 形式/后代::m_uuid[1]的模式在这两种情况下都是不合法的 XSLT1.0或XSLT2.0,尽管在XSLT3.0中它是合法的 您对

我需要将所有内容复制到新的XML中,除了一些需要重命名的元素

所有属于“node1”子节点的“child”节点需要重命名为“children”,属于“node2”子节点的“child”节点需要重命名为“kid”

完美的解决方案将使用

match="/root/node1/descendant::child"
但正如我在迈克尔·凯对这个话题的回应中所发现的那样

形式/后代::m_uuid[1]的模式在这两种情况下都是不合法的 XSLT1.0或XSLT2.0,尽管在XSLT3.0中它是合法的

您对如何在XSLT2.0中做到这一点有什么建议,而不必执行下面的操作?因为我不知道到底会有多少窝

下面是我的xml示例

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>

和XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="/root/node1/child">
        <xsl:element name="children">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="/root/node1/child/subnode/child">
        <xsl:element name="children">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="/root/node2/child">
        <xsl:element name="kid">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="/root/node2/child/subnode/child">
        <xsl:element name="kid">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

这对你有用吗

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="child">
    <children>
        <xsl:apply-templates select="@*|node()"/>
    </children>
</xsl:template>

<xsl:template match="child[ancestor::node2]">
    <kid>
        <xsl:apply-templates select="@*|node()"/>
    </kid>
</xsl:template>

</xsl:stylesheet>

您可以在模式中使用
//child

<xsl:template match="/root/node1//child">
    <xsl:element name="children">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>


<xsl:template match="/root/node2//child">
    <xsl:element name="kid">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

我将使用文本结果元素而不是xsl:element:

<xsl:template match="/root/node1//child">
    <children>
        <xsl:apply-templates select="@*|node()"/>
    </children>
</xsl:template>


<xsl:template match="/root/node2//child">
    <kid>
        <xsl:apply-templates select="@*|node()"/>
    </kid>
</xsl:template>

此解决方案根本不使用任何谓词或轴,具有最短的匹配模式,因此比使用谓词的解决方案效率更高

有后代或祖先时,它也会产生预期的正确结果
——这是其他解决方案根本无法处理的

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="node()|@*" mode="#all">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" mode="#current"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node1" mode="#all">
     <xsl:copy>
      <xsl:apply-templates select="node()|@*" mode="node1"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node2" mode="#all">
     <xsl:copy>
      <xsl:apply-templates select="node()|@*" mode="node2"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="child" mode="node1">
    <children>
      <xsl:apply-templates select="node()|@*" mode="#current"/>
    </children>
  </xsl:template>
  <xsl:template match="child" mode="node2">
    <kid>
      <xsl:apply-templates select="node()|@*" mode="#current"/>
    </kid>
  </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时

<root>
    <node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>
<root>
    <node1>
        <child>
            <subnode>
              <node2>
                  <child></child>
                  <node1>
                    <child/>
                  </node1>            
              </node2>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <node1>
            <child>
                <subnode>
                    <child></child>
                </subnode>
            </child>
        </node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>
<root>
      <node1>
            <children>
                  <subnode>
                     <node2>
                           <kid/>
                           <node1>
                              <children/>
                           </node1>           
                     </node2>
                  </subnode>
            </children>
            <children>
                  <subnode>
                        <children/>
                  </subnode>
            </children>
      </node1>
      <node2>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
            </kid>
            <node1>
                  <children>
                        <subnode>
                              <children/>
                        </subnode>
                  </children>
            </node1>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
            </kid>
      </node2>
</root>

生成所需的正确结果:

<root>
      <node1>
            <children>
                  <subnode>
                        <children/>
                  </subnode>
      </children>
            <children>
                  <subnode>
                        <children/>
                  </subnode>
      </children>
      </node1>
      <node2>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
      </kid>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
      </kid>
      </node2>
</root>

在此XML文档上应用相同转换时,其中
是彼此的后代或祖先

<root>
    <node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>
<root>
    <node1>
        <child>
            <subnode>
              <node2>
                  <child></child>
                  <node1>
                    <child/>
                  </node1>            
              </node2>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <node1>
            <child>
                <subnode>
                    <child></child>
                </subnode>
            </child>
        </node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>
<root>
      <node1>
            <children>
                  <subnode>
                     <node2>
                           <kid/>
                           <node1>
                              <children/>
                           </node1>           
                     </node2>
                  </subnode>
            </children>
            <children>
                  <subnode>
                        <children/>
                  </subnode>
            </children>
      </node1>
      <node2>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
            </kid>
            <node1>
                  <children>
                        <subnode>
                              <children/>
                        </subnode>
                  </children>
            </node1>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
            </kid>
      </node2>
</root>

再次生成正确且想要的结果(由其最近的祖先(即
)确定的
的替换名称):

<root>
    <node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>
<root>
    <node1>
        <child>
            <subnode>
              <node2>
                  <child></child>
                  <node1>
                    <child/>
                  </node1>            
              </node2>
            </subnode>
        </child>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node1>
    <node2>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
        <node1>
            <child>
                <subnode>
                    <child></child>
                </subnode>
            </child>
        </node1>
        <child>
            <subnode>
                <child></child>
            </subnode>
        </child>
    </node2>
</root>
<root>
      <node1>
            <children>
                  <subnode>
                     <node2>
                           <kid/>
                           <node1>
                              <children/>
                           </node1>           
                     </node2>
                  </subnode>
            </children>
            <children>
                  <subnode>
                        <children/>
                  </subnode>
            </children>
      </node1>
      <node2>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
            </kid>
            <node1>
                  <children>
                        <subnode>
                              <children/>
                        </subnode>
                  </children>
            </node1>
            <kid>
                  <subnode>
                        <kid/>
                  </subnode>
            </kid>
      </node2>
</root>


是的,它在我原来的10k行XML文档上运行良好。谢谢你的解决方案。你的解决方案对我也很好。谢谢回复。你能解释一下为什么要使用文字结果元素吗?当我必须向样式表标记添加排除结果前缀时,我只注意到使用文字时的区别,因为我在文件中使用名称空间。使用文字结果元素,您必须编写更少的代码,并且在我看来,样式表的功能更清晰(例如,将
node1//child
映射到
children
),我只在运行时需要计算元素的名称和/或命名空间时才使用
xsl:element
。好的,我明白了。再次感谢。在我的原始文件中,我没有和是彼此的后代或祖先的情况,但感谢这个例子。我必须阅读一些关于“模式”的内容,我会将您的解决方案应用到我的原始文件中,看看它是如何工作的。@Elej,我很高兴这个答案不仅解决了您当前的问题,而且解决了未来的问题:)欢迎您进一步询问。