【问题标题】:xslt how to change the tag name of child node recursivelyxslt如何递归更改子节点的标签名称
【发布时间】:2017-08-17 09:46:24
【问题描述】:

我在下面的表格中有我的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"/>

【问题讨论】:

  • 一个例子是不够的:请用文字解释所需的逻辑。

标签: xml xslt xpath xml-parsing dita


【解决方案1】:

这应该可行:

<?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>

【讨论】:

    【解决方案2】:

    这是一个 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>
    

    【讨论】:

    • 您可以制作第一个模板match="topicref[not(parent::topicref)]" 并消除第二个模板。如果这是这里的预期逻辑。
    • @michael.hor257k:我用两个(而不是三个)模板对其进行了测试,问题是复制了内部topicref 的outputclass 属性。所以无论如何我需要第二个/第三个模板......我也想知道预期的结构,但没有进一步的信息,这是最好的。
    猜你喜欢
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2018-02-10
    相关资源
    最近更新 更多