如何使用xslt删除最外层的包装器?

时间:2012-11-28 23:33:59

标签: xml xslt

示例xml是:

<a amp="a"><b><c>this is the text</c></b></a>

需要转变为:

<a amp="a"><c>this is the text</c></a>

2 个答案:

答案 0 :(得分:3)

解决方案#1: smaccoun 的解决方案略有改进,该解决方案将保留c元素上的所有属性(对于示例XML不是必需的):

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

解决方案#2 另一种利用 built-in template rules 的替代方案,它为所有元素应用模板并复制所有text()

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <!--identity template for the c element, it's decendant nodes, 
        and attributes (which will only get applied from c or 
        descendant elements)-->
    <xsl:template match="@*|c//node()|c">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

解决方案#3:修改后的 identity transform:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <!--identity template, copies all content by default-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!--don't generate content for these matched elements, 
        just apply-templates to it's children-->
    <xsl:template match="a|b">
        <xsl:apply-templates/>
    </xsl:template>     
</xsl:stylesheet>

解决方案#4 如果您知道自己想要什么,只需从根节点上的匹配中复制

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <xsl:copy-of select="a/b/c" />
    </xsl:template>
</xsl:stylesheet>

如果您只想从输入中删除<b>元素,那么修改后的身份转换应与匹配<b>元素的模板一起使用,该模板只是将模板应用于其子项。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <!--identity template, copies all content by default-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!--don't generate content for the <b>, just apply-templates to it's children-->
    <xsl:template match="b">
        <xsl:apply-templates/>
    </xsl:template>     
</xsl:stylesheet>

答案 1 :(得分:1)

<c>上应用模板,然后只使用复制设计模式。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match='c'>
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>