XSLT节点过滤问题:移除含Descriptor=ID1的节点报错求解
移除含Descriptor=ID1的Reference节点时XSLT报错问题
我尝试移除XML中Descriptor="ID1"的<Reference>节点,但执行XSLT时出现错误,以下是相关代码、报错信息及期望输出:
XML源数据
<?xml version='1.0' encoding='UTF-8'?> <Data> <Entry> <Line>1</Line> <Reference Descriptor="ID1"> <ID type="ID">gbgfdbnfg</ID> </Reference> <Reference Descriptor="ID2"> <ID type="ID">tshbtdsg</ID> </Reference> <Reference Descriptor="ID3"> <ID type="ID">rhbdgb</ID> </Reference> </Entry> </Data>
错误的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*[contains(Reference/@Descriptor,'ID1')]"> <!-- Do nothing --> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
报错信息
序列包含多个项目,无法作为
fn:contains()的第一个参数(传入了"ID1", "ID2")
期望输出
<?xml version='1.0' encoding='UTF-8'?> <Data> <Entry> <Line>1</Line> <Reference Descriptor="ID2"> <ID type="ID">tshbtdsg</ID> </Reference> <Reference Descriptor="ID3"> <ID type="ID">rhbdgb</ID> </Reference> </Entry> </Data>
问题分析与解决方案
错误原因
原XSLT的匹配逻辑*[contains(Reference/@Descriptor,'ID1')]存在问题:Reference/@Descriptor会返回当前节点下所有<Reference>的Descriptor属性值(比如<Entry>节点下会得到"ID1","ID2","ID3"三个值),而fn:contains()要求第一个参数是单一字符串,传入多值序列就会触发报错。
修正后的XSLT代码
直接精准匹配要删除的<Reference>节点,此处为精确匹配,用相等判断更合适:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配Descriptor为ID1的Reference节点,不输出该节点 --> <xsl:template match="Reference[@Descriptor='ID1']"/> <!-- 身份模板:复制所有其他节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
说明
修改后的代码通过直接匹配目标节点,避免了多值序列的问题。身份模板会复制所有未被特殊模板匹配的节点和属性,最终生成符合期望的XML输出。
内容的提问来源于stack exchange,提问作者user9324800
相关产品推荐
相关产品推荐

