XSLT排序问题:基于重复OCC1字段的OCC2排序异常排查
XSLT排序问题:OCC1值重复时按OCC2值排序
需求说明
对LULineItem节点排序时,遵循以下规则:
- 优先按
IdenType=OCC1的IdenValue排序 - 当多个
LULineItem的OCC1值重复时,这些重复项内部按IdenType=OCC2的IdenValue排序
当前使用的XSLT未正确实现该逻辑,导致排序结果不符合预期。
输入示例
<Root> <LULineItem> <Identifier> <IdenType>OCC1</IdenType> <IdenValue>1234</IdenValue> </Identifier> <Identifier> <IdenType>OCC2</IdenType> <IdenValue>B</IdenValue> </Identifier> </LULineItem> <LULineItem> <Identifier> <IdenType>OCC1</IdenType> <IdenValue>4567</IdenValue> </Identifier> <Identifier> <IdenType>OCC2</IdenType> <IdenValue>C</IdenValue> </Identifier> </LULineItem> <LULineItem> <Identifier> <IdenType>OCC1</IdenType> <IdenValue>4567</IdenValue> </Identifier> <Identifier> <IdenType>OCC2</IdenType> <IdenValue>A</IdenValue> </Identifier> </LULineItem> </Root>
期望输出
<Root> <LULineItem> <Identifier> <IdenType>OCC1</IdenType> <IdenValue>1234</IdenValue> </Identifier> <Identifier> <IdenType>OCC2</IdenType> <IdenValue>B</IdenValue> </Identifier> </LULineItem> <LULineItem> <Identifier> <IdenType>OCC1</IdenType> <IdenValue>4567</IdenValue> </Identifier> <Identifier> <IdenType>OCC2</IdenType> <IdenValue>A</IdenValue> </Identifier> </LULineItem> <LULineItem> <Identifier> <IdenType>OCC1</IdenType> <IdenValue>4567</IdenValue> </Identifier> <Identifier> <IdenType>OCC2</IdenType> <IdenValue>C</IdenValue> </Identifier> </LULineItem> </Root>
当前XSLT(问题代码)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <Root> <xsl:for-each select="Root/LULineItem"> <xsl:sort select="Identifier[IdenType='OCC1']/IdenValue" data-type="text"/> <xsl:copy-of select="."/> </xsl:for-each> </Root> </xsl:template> </xsl:stylesheet>
问题分析
当前代码仅指定了OCC1作为唯一排序键,当OCC1值重复时,XSLT会保留节点的原始文档顺序,不会自动触发OCC2的排序逻辑,因此无法满足需求。
修正后的XSLT
XSLT 1.0版本
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <Root> <xsl:for-each select="Root/LULineItem"> <!-- 第一优先级:按OCC1的值排序 --> <xsl:sort select="Identifier[IdenType='OCC1']/IdenValue" data-type="text"/> <!-- 第二优先级:OCC1重复时,按OCC2的值排序 --> <xsl:sort select="Identifier[IdenType='OCC2']/IdenValue" data-type="text"/> <xsl:copy-of select="."/> </xsl:for-each> </Root> </xsl:template> </xsl:stylesheet>
XSLT 2.0+版本
如果使用XSLT 2.0或更高版本,也可以用xsl:perform-sort实现,逻辑一致:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <Root> <xsl:perform-sort select="Root/LULineItem"> <xsl:sort select="Identifier[IdenType='OCC1']/IdenValue"/> <xsl:sort select="Identifier[IdenType='OCC2']/IdenValue"/> </xsl:perform-sort> </Root> </xsl:template> </xsl:stylesheet>
逻辑说明
- 第一级排序确保所有节点先按OCC1的值分组排序
- 第二级排序针对OCC1值相同的节点组,进一步按OCC2的值排序,完美匹配需求
内容的提问来源于stack exchange,提问作者Padd T
相关产品推荐
相关产品推荐

