XSLT过滤需求:移除子节点externalCode为'T'的EmpEmployment节点
XSLT实现移除指定条件的EmpEmployment节点
问题背景
输入XML如下:
<PerNationalId> <PerNationalId> <nationalId>999.999.868-88</nationalId> <personNav> <PerPerson> <employmentNav> <EmpEmployment> <empWorkPermitNav> <EmpWorkPermit> <documentNumber>27122165960</documentNumber> <issuePlaceNav/> <customString3/> <documentTypeNav> <PicklistOption> <externalCode>6</externalCode> </PicklistOption> </documentTypeNav> </EmpWorkPermit> </empWorkPermitNav> <jobInfoNav> <EmpJob> <emplStatusNav> <PicklistOption> <externalCode>T</externalCode> </PicklistOption> </emplStatusNav> <company>0004</company> </EmpJob> </jobInfoNav> <userId>60020077</userId> </EmpEmployment> <EmpEmployment> <empWorkPermitNav> <EmpWorkPermit> <documentNumber>320008725351</documentNumber> <issuePlaceNav/> <customString3/> <documentTypeNav> <PicklistOption> <externalCode>3</externalCode> </PicklistOption> </documentTypeNav> </EmpWorkPermit> </empWorkPermitNav> <jobInfoNav> <EmpJob> <emplStatusNav> <PicklistOption> <externalCode>A</externalCode> </PicklistOption> </emplStatusNav> <company>0004</company> </EmpJob> </jobInfoNav> <userId>20028939</userId> </EmpEmployment> </employmentNav> </PerPerson> </personNav> </PerNationalId> </PerNationalId>
期望输出XML:
<PerNationalId> <PerNationalId> <nationalId>999.999.868-88</nationalId> <personNav> <PerPerson> <employmentNav> <EmpEmployment> <empWorkPermitNav> <EmpWorkPermit> <documentNumber>320008725351</documentNumber> <issuePlaceNav/> <customString3/> <documentTypeNav> <PicklistOption> <externalCode>3</externalCode> </PicklistOption> </documentTypeNav> </EmpWorkPermit> </empWorkPermitNav> <jobInfoNav> <EmpJob> <emplStatusNav> <PicklistOption> <externalCode>A</externalCode> </PicklistOption> </emplStatusNav> <company>0004</company> </EmpJob> </jobInfoNav> <userId>20028939</userId> </EmpEmployment> </employmentNav> </PerPerson> </personNav> </PerNationalId> </PerNationalId>
核心需求:移除内部子节点路径jobInfoNav/EmpJob/emplStatusNav/PicklistOption/externalCode值等于'T'的EmpEmployment节点。
尝试过的错误XSLT
之前的代码仅移除了emplStatusNav标签,未达到预期效果:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/PerNationalId/PerNationalId/personNav/PerPerson/employmentNav/EmpEmployment/jobInfoNav/EmpJob/emplStatusNav/PicklistOption[(externalCode= 'T')]"/> </xsl:stylesheet>
修正后的XSLT解决方案
直接匹配需要移除的EmpEmployment节点,通过条件筛选实现需求:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 默认复制所有节点和属性的身份转换模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配并移除符合条件的EmpEmployment节点 --> <xsl:template match="EmpEmployment[jobInfoNav/EmpJob/emplStatusNav/PicklistOption/externalCode = 'T']"/> </xsl:stylesheet>
方案说明
- 原代码错误地匹配了
PicklistOption节点,所以仅移除了该节点而非上级的EmpEmployment。 - 修正后的模板直接定位到
EmpEmployment节点,通过谓词[jobInfoNav/EmpJob/emplStatusNav/PicklistOption/externalCode = 'T']筛选出需要移除的目标节点,匹配到的节点不会被复制,从而实现移除整个EmpEmployment的效果。 - 身份转换模板保证了其他无需处理的节点和属性正常保留。
内容的提问来源于stack exchange,提问作者Carlos Moraes
相关产品推荐
相关产品推荐

