You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改XSLT模板保留attr属性中b值非空的元素?

问题:调整XSLT以保留特定属性非空的元素

我之前编写了一段XSLT,用于移除所有空元素及其父元素,但perm元素无论是否为空都必须保留。现在需要修改这段代码,实现保留attr属性中b值非空的元素,尝试使用contains函数但未得到预期效果。

原XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[not(self::perm)][not(descendant::text()[normalize-space()])]" />

</xsl:stylesheet>

源XML

<?xml version="1.0" encoding="UTF-8"?>
<item>
    <perm desc="item_1" attr="a='';b=''">
        <content>
            <notuse></notuse>
        </content>
        <desc>Item 1</desc>
        <details>
            <firstname desc="Name" attr="a='';b=''">John</firstname>
            <lastname desc="Last" attr="a='';b=''"></lastname>
            <phone desc="phone" attr="a='';b='561-663-1254'"></phone>
        </details>
    </perm>    
    <perm desc="item_2" attr="a='';b=''"></perm>    
</item>

预期结果

<item>
    <perm desc="item_1" attr="a='';b=''">        
        <desc>Item 1</desc>
        <details>
            <firstname desc="Name" attr="a='';b=''">John</firstname>            
            <phone desc="phone" attr="a='';b='561-663-1254'"></phone>
        </details>
    </perm>    
    <perm desc="item_2" attr="a='';b=''"></perm>    
</item>

解决方案

调整后的XSLT代码

要实现需求,需要修改匹配空元素的模板,增加对attr属性中b值的判断逻辑,排除那些b值非空的元素。

方法一:使用contains快速判断

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- 仅移除:非perm元素、无空文本后代、且attr中b值为空的元素 -->
<xsl:template match="*[
    not(self::perm) 
    and not(descendant::text()[normalize-space()]) 
    and contains(@attr, 'b=''')
]" />

</xsl:stylesheet>

方法二:精准提取b值判断(更严谨)

如果需要更精准的判断,可以通过字符串截取提取b的值:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- 提取b的值,判断是否为空字符串 -->
<xsl:template match="*[
    not(self::perm) 
    and not(descendant::text()[normalize-space()]) 
    and substring-before(substring-after(@attr, 'b='), ';') = ''''
]" />

</xsl:stylesheet>

逻辑说明

  • 原模板仅判断元素是否有非空文本后代,现在新增了attr属性的检查:
    • 方法一通过contains(@attr, 'b=''')判断元素的b值是否为空,仅移除符合条件的空元素;
    • 方法二通过substring-after和substring-before精准提取b的取值,判断是否为空字符串,避免属性值中出现类似b='';xxx的误判。

内容的提问来源于stack exchange,提问作者Somebody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:17:53