如何用XSLT判断XML特定值并过滤对应记录?
解决XML映射中的特定值过滤问题
刚好做过类似的XML转换过滤需求,用XSLT就能完美搞定这个问题,我基于你给的简化示例,整理了两种常见场景的实现方案,你可以根据实际需求调整:
场景1:过滤包含特定code的单个EmploymentPeriod节点
如果你的需求是只要某个EmploymentPeriod下的lart元素有目标code值,就跳过这个EmploymentPeriod的映射,可以用下面的XSLT实现:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://Schema1"> <!-- 定义要过滤的code值,后续修改直接改这里就行 --> <xsl:param name="filterCode" select="'0674'"/> <!-- 身份转换模板:默认复制所有节点和属性,保证非目标节点正常映射 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 过滤包含目标code的EmploymentPeriod节点 --> <xsl:template match="ns0:EmploymentPeriod[ns0:lart/@code=$filterCode]"> <!-- 空模板:不输出该节点,实现过滤效果 --> </xsl:template> </xsl:stylesheet>
代码说明:
- 先声明了XML里的
ns0命名空间,确保能正确匹配到所有目标节点; filterCode参数做了抽离,后续要换过滤值不用改核心逻辑;- 身份模板保证所有没被特殊处理的节点都会原样复制到目标Schema;
- 针对包含目标code的
EmploymentPeriod写了空模板,直接跳过输出,精准过滤。
场景2:过滤包含特定code的整个Person节点
如果你的需求是只要某个Person下存在任何一个EmploymentPeriod包含目标code,就跳过整个Person的映射,可以调整模板为:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://Schema1"> <xsl:param name="filterCode" select="'0674'"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 过滤包含目标code的Person节点 --> <xsl:template match="ns0:Person[.//ns0:lart/@code=$filterCode]"> <!-- 空模板:不输出该节点 --> </xsl:template> </xsl:stylesheet>
测试效果
用你提供的简化XML测试:
<ns0:Root xmlns:ns0="http://Schema1"> <Person> <Employment> <EmploymentPeriod> <lart code="0674" /> </EmploymentPeriod> <EmploymentPeriod> <lart code="2222" /> </EmploymentPeriod> </Employment> </Person> </ns0:Root>
- 场景1转换后:会保留code="2222"的
EmploymentPeriod,去掉code="0674"的节点; - 场景2转换后:整个
Person节点都会被过滤掉。
如果你的目标Schema有特定结构,也可以在身份模板的基础上,修改输出的节点字段,同时保留这套过滤逻辑就行。
内容的提问来源于stack exchange,提问作者Morgan
相关产品推荐
相关产品推荐

