【问题标题】:How do I remove the outermost wrappers using xslt?如何使用 xslt 删除最外层的包装?
【发布时间】:2012-11-30 11:10:18
【问题描述】:

示例 xml 是:

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

需要转化为:

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

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    解决方案 #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>
    

    如果您只想从输入中删除 &lt;b&gt; 元素,则应将修改后的身份转换与匹配 &lt;b&gt; 元素的模板一起使用,该模板仅将模板应用于其子元素。

    <?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。此外,身份转换模式是我想到的名称,而不是“复制设计模式”。不知道它会将属性复制为文本,很高兴知道!
    • 疯子,你能看看我所做的编辑吗?我想保留 a 但要删除 b
    • 您可能想使用解决方案#3,只需从匹配条件中删除a,以便由@*|node() 上的通用匹配处理,这将复制内容。 b 上的匹配将抑制其内容,但将模板应用于其子级,这也将匹配复制到输出的通用模板。
    【解决方案2】:

    &lt;c&gt; 上应用模板,然后只使用复制设计模式。

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

    【讨论】:

    • 这适用于这个实例文档。但是,如果&lt;c&gt; 具有属性,则这些值将被复制为文本内容,而不是被保留。 (例如&lt;c amp="foo"&gt;this is the text&lt;/c&gt; 将导致&lt;c&gt;foothis is the text&lt;/c&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多