Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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
Xml xslt如何递归更改子节点的标记名_Xml_Xslt_Xpath_Xml Parsing_Dita - Fatal编程技术网

Xml xslt如何递归更改子节点的标记名

Xml xslt如何递归更改子节点的标记名,xml,xslt,xpath,xml-parsing,dita,Xml,Xslt,Xpath,Xml Parsing,Dita,我的xml内容如下表所示,附录中也可以有任意数量的子项 <topicref outputclass="Dx:Appendix" href="AppendixA-test.dita"> <topicref outputclass="Dx:Appendix" href="AppendixA-sub-test.dita"/> </topicref> <topicref outputclass="Dx:Appendix" href="Append

我的
xml
内容如下表所示,附录中也可以有任意数量的子项

<topicref outputclass="Dx:Appendix" href="AppendixA-test.dita">
    <topicref outputclass="Dx:Appendix" href="AppendixA-sub-test.dita"/>
  </topicref>
  <topicref outputclass="Dx:Appendix" href="AppendixB-test.dita"/>

现在我希望我的输出xml如下所示:

<appendix href="AppendixA-test.dita">
      <topicref href="AppendixA-sub-test.dita"/>
    </appendix>
    <appendix href="AppendixB-test.dita"/>

这是一个XSLT-1.0解决方案:

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

  <!-- copy all nodes except those more specific -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

  <!-- modify all "topicref" nodes except those more specific -->
  <xsl:template match="topicref">
    <xsl:element name="appendix">
      <xsl:apply-templates select="node()|@href" />
    </xsl:element>
  </xsl:template>

  <!-- do not modify the names of "topicref" elements with "topicref" parents" -->
  <xsl:template match="topicref[parent::topicref]">
    <xsl:copy>
      <xsl:apply-templates select="node()|@href" />
    </xsl:copy>
  </xsl:template>  

</xsl:stylesheet>

这应该可以:

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

    <!-- 
        Convert first-level <topicref> elements to <appendix> and copy the attributes,
        but ignore the @outputclass attribute
    -->
    <xsl:template match="topicref[contains(@outputclass, 'Dx:Appendix')][not(parent::topicref)]">
        <appendix>
            <xsl:apply-templates select="@*[name()!='outputclass'] | node()"/>
        </appendix>
    </xsl:template>

    <!--
        Copy all elements and attributes, except the @outputclass attribute
        (default copy template)
    -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*[name()!='outputclass'] | node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>


仅举一个例子是不够的:请用文字解释所需的逻辑。您可以制作第一个模板
match=“topicref[not(parent::topicref)]”
并删除第二个模板。如果这是这里的预期逻辑。@michael.hor257k:我用两个(而不是三个)模板测试了它,问题是内部
topicref
outputclass
属性被复制了。所以不管怎样,我需要第二个/第三个模板。。。我还想知道预期的结构,但没有进一步的信息,这是最好的。