如何合并两个XSLT文件实现节点过滤与空节点移除?
合并XSLT实现XML节点过滤与清理
现有XML数据
<?xml version="1.0" encoding="UTF-8"?> <root> <record> <Position> <Customer_Cost_EUR>13.218.400.000.000.000</Customer_Cost_EUR> t> <Charge_Type>cycleCharge</Charge_Type> <Customer_Company>GmbH + Co. KG</Customer_Company> <Customer_ID>98079</Customer_ID> <Kundennummer_customer /> </Position> <Position> <Customer_Cost_EUR>23.510.400.000.000.000</Customer_Cost_EUR> <Charge_Type>addQuantity</Charge_Type> <Customer_ID>98079</Customer_ID> <Kundennummer_customer /> </Position> <Position> <Customer_Cost_EUR>0</Customer_Cost_EUR> <Charge_Type>new</Charge_Type> <Customer_ID>98079</Customer_ID> <Kundennummer_customer /> </Position> </record> <record> <Position> <Customer_Cost_EUR>23.510.400.000.000.000</Customer_Cost_EUR> <Charge_Type>addQuantity</Charge_Type> <Customer_ID>98079</Customer_ID> <Kundennummer_customer /> </Position> <Position> <Customer_Cost_EUR>23.510.400.000.000.000</Customer_Cost_EUR> <Charge_Type>worktime</Charge_Type> <Customer_ID>98079</Customer_ID> <Kundennummer_customer /> </Position> </record> </root>
需求说明
- 移除所有
Charge_Type值不为new、renew或cycleCharge的Position节点 - 若某个
record节点下没有剩余的Position节点,则移除该record节点
目标XML效果
<root> <record> <Position> <Customer_Cost_EUR>13.218.400.000.000.000</Customer_Cost_EUR>t> <Charge_Type>cycleCharge</Charge_Type> <Customer_Company>GmbH + Co. KG</Customer_Company> <Customer_ID>98079</Customer_ID> <Kundennummer_customer/> </Position> <Position> <Customer_Cost_EUR>0</Customer_Cost_EUR> <Charge_Type>new</Charge_Type> <Customer_ID>98079</Customer_ID> <Kundennummer_customer/> </Position> </record> <record> <Position> <Customer_Cost_EUR>10</Customer_Cost_EUR> <Charge_Type>renew</Charge_Type> <Customer_ID>98018</Customer_ID> <Kundennummer_customer/> </Position> </record> </root>
现有两个独立XSLT文件
第一个(过滤不符合条件的Position)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="Position[Charge_Type!='renew' and Charge_Type!='new' and Charge_Type!='cycleCharge' ]"/> </xsl:stylesheet>
第二个(移除无有效Position的record)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" /> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="record[not(descendant::Customer_ID)]"/> </xsl:stylesheet>
合并后的XSLT方案
将两个模板整合到同一个XSLT文件中,同时优化record节点的判断逻辑,确保直接检查是否存在符合要求的Position节点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" /> <!-- 身份模板:复制所有未被特殊模板匹配的节点 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 移除Charge_Type不符合要求的Position节点 --> <xsl:template match="Position[not(Charge_Type='renew' or Charge_Type='new' or Charge_Type='cycleCharge')]"/> <!-- 移除没有有效Position节点的record --> <xsl:template match="record[not(Position[Charge_Type='renew' or Charge_Type='new' or Charge_Type='cycleCharge'])]"/> </xsl:stylesheet>
说明
- 保留核心身份模板,确保未被过滤的节点正常复制
- 一次处理即可完成Position过滤与空record清理两个需求
- 优化record节点的判断逻辑,直接检查是否存在符合要求的Position,避免原逻辑依赖Customer_ID可能出现的误差
内容的提问来源于stack exchange,提问作者Eminen
相关产品推荐
相关产品推荐

