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

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

问题描述:

我在下面的表单中有我的xml内容,其中附录可以有任何no。的子女也是如此。xslt如何递归地更改子节点的标记名称

<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"/> 
+0

一个例子是不够的:p用言语解释所需的逻辑。 –

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

你可以制作第一个模板match =“topicref [not(parent :: topicref)]”'并且消除第二个模板。如果这是预期的逻辑。 –

+0

@ michael.hor257k:我用两个(而不是三个)模板测试了它,问题是复制了'topicref'的'outputclass'属性。所以,无论如何,我需要第二个/第三个模板......我也想知道预期的结构,但没有进一步的信息,这是一样好。 – zx485

这应该工作:

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