XSLT 3中如何处理dmCode变量差集并合并执行流程
实现先处理指定节点再处理剩余节点的XSLT方案
要实现先处理$flight-DMs,再处理$all-DMs中未包含在$flight-DMs里的节点,不需要依赖union(union会按文档顺序合并去重,不符合你“先全部航班节点再剩余节点”的顺序要求),直接分两次处理更直观,以下是针对不同XSLT版本的实现方案:
XSLT 2.0+ 版本(支持节点集运算符)
利用intersect运算符判断节点是否属于$flight-DMs,直接筛选出剩余节点:
<!-- 定义变量 --> <xsl:variable name="all-DMs" select="//dmCode"/> <xsl:variable name="flight-DMs" select="$all-DMs[../infoCode = ('130','131')]"/> <!-- 第一步:处理航班相关的dmCode节点 --> <xsl:apply-templates select="$flight-DMs"/> <!-- 第二步:处理所有不在flight-DMs里的dmCode节点 --> <xsl:apply-templates select="$all-DMs[not(. intersect $flight-DMs)]"/>
XSLT 1.0 版本(无原生节点集差集运算符)
XSLT 1.0不支持intersect,可以通过节点集合并后的计数判断,或者使用key来匹配:
方法1:计数判断法
<xsl:variable name="all-DMs" select="//dmCode"/> <xsl:variable name="flight-DMs" select="$all-DMs[../infoCode = '130' or ../infoCode = '131']"/> <!-- 处理航班节点 --> <xsl:apply-templates select="$flight-DMs"/> <!-- 处理剩余节点:判断节点合并到flight-DMs后总数是否不变,不变说明已存在 --> <xsl:apply-templates select="$all-DMs[not(count(. | $flight-DMs) = count($flight-DMs))]"/>
方法2:Key匹配法
先给$flight-DMs创建索引,再通过key筛选剩余节点:
<xsl:key name="flight-dm" match="dmCode" select="."/> <xsl:variable name="all-DMs" select="//dmCode"/> <xsl:variable name="flight-DMs" select="$all-DMs[../infoCode = ('130','131')]"/> <!-- 处理航班节点 --> <xsl:apply-templates select="$flight-DMs"/> <!-- 处理剩余节点:通过key判断当前节点是否在flight-DMs中 --> <xsl:apply-templates select="$all-DMs[not(key('flight-dm', .))]"/>
关于union的说明
如果一定要用union,注意$flight-DMs | $all-DMs会自动去重,但节点顺序是原文档中的出现顺序,而不是先全部$flight-DMs再剩余节点,所以不符合你的需求。如果必须用union来组合节点集并保证顺序,需要先将$flight-DMs和剩余节点分别存为变量,再union这两个变量:
<xsl:variable name="remaining-DMs" select="$all-DMs[not(. intersect $flight-DMs)]"/> <xsl:apply-templates select="$flight-DMs | $remaining-DMs"/>
这种写法和分两次apply-templates效果一致,但不如直接分两次处理清晰。
内容的提问来源于stack exchange,提问作者Caroline
相关产品推荐
相关产品推荐

