【问题标题】:XSLT 2.0: Remove nodes from input XML based on conditionXSLT 2.0:根据条件从输入 XML 中删除节点
【发布时间】:2021-09-30 11:47:22
【问题描述】:

我有一个可能包含多个就业信息节点的 XML。我需要选择具有子字段 assignment_class 为“GA”的那个。其他的就业信息节点应该被丢弃。 另外,如果employment_information节点只有一个,那么就直接通过吧。

输入 XML:

<?xml version="1.0" encoding="utf-8"?>
<queryCompoundEmployeeResponse>
   <CompoundEmployee>
      <Person>
         <StartDate>2012-02-01</StartDate>
         <EndDate>2019-02-28</EndDate>
         <action>NO CHANGE</action>             
         <employment_information>
            <action>NO CHANGE</action>
            <assignment_class>ST</assignment_class>
         </employment_information>
         <employment_information>
            <action>NO CHANGE</action>
            <assignment_class>GA</assignment_class>
         </employment_information>
      </Person>
</CompoundEmployee>
</queryCompoundEmployeeResponse>

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
<queryCompoundEmployeeResponse>
   <CompoundEmployee>
      <Person>
         <StartDate>2012-02-01</StartDate>
         <EndDate>2019-02-28</EndDate>
         <action>NO CHANGE</action>
         <employment_information>
            <action>NO CHANGE</action>
            <assignment_class>GA</assignment_class>
         </employment_information>
      </Person>
   </CompoundEmployee>
</queryCompoundEmployeeResponse>

在参考了一些在线帖子后,我可以使用下面的 XSLT 部分实现这一点:

<?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" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="//Person/employment_information[assignment_class!='GA']"/>
</xsl:stylesheet>

但我需要增强此 XSLT 以最终具有以下逻辑:

  1. 统计就业信息
  2. 如果 Count 大于 1,则选择 assignment_class 为“GA”的就业信息以及输入中的其他节点。
  3. 否则(即,如果计数为 0 或 1)按原样复制输入到输出。

感谢任何帮助。谢谢!

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    如果我没看错的话,这里有一种你可以看的方式:

    <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="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="employment_information[assignment_class!='GA' and count(../employment_information) gt 1]"/>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 非常感谢!并为迟到的反应道歉。您能否简要解释一下第二个模板是如何/具体在做什么的?我了解第一个模板只是复制所有内容。但是,为什么在进入第二个模板之前,这也不用“GA”复制节点?再次感谢!
    • XSLT 处理模型的工作方式类似于this: "输入序列中的每个节点都通过查找与该节点的模式匹配的模板规则进行处理。如果有多个,则最好其中被选中...”。在此示例中,第二个模板更适合带有“GA”的节点,因为它是特定于节点的 - 请参阅:w3.org/TR/xslt20/#conflict
    • 非常感谢你,迈克尔!将通过参考链接。
    猜你喜欢
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多