我在对段进行排序时遇到问题,我需要分别对段 Node/ITEM 和 Node/LINE 段进行排序,
Node/ITEM 排序:我们需要检查 Node/ITEM 是否存在,然后 Node/ITEM/LINE/FIER/VALUE 是否在另一个 Node/ITEM/LINE/FIER/Value 中重复,其中 Type=Key1,如果重复则基于ITEM/LINE/FIER/VALUE (Type=Key2) 我们需要执行排序。
Node/LINE 排序: 同上,如果 Node/LINE 存在,则可以根据 Node/LINE/FIER/VALUE 进行排序。
我找到了几乎类似的例子,但是XSLT完全删除了Node/LINE,它能够正确地进行Node/ITEM排序。 请审核一次
输入:
<SBD>
<DOCUMENT>
<Field1> value1</Field1>
</DOCUMENT>
<Node>
<ship>123</ship>
<field2>345r</field2>
<ITEM>
<IDENT>
<CODE>
<Value>67896789</Value>
</CODE>
</IDENT>
<LINE number="1">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>555</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>XYZ</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
</ITEM>
<ITEM>
<IDENT>
<CODE>
<Value>3243</Value>
</CODE>
</IDENT>
<LINE number="2">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>444</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>BBBB</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<Segment1>
<subsegment>
<value>123</value>
</subsegment>
</Segment1>
</ITEM>
<ITEM>
<IDENT>
<CODE>
<Value>0870</Value>
</CODE>
</IDENT>
<LINE number="3">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>444</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>No</VALUE>
<TYPE>Key3</TYPE>
</FIER>
<FIER>
<VALUE>AAA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
</ITEM>
<LINE number="1">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>6382</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>REA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<LINE number="2">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>5678</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>CBA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<LINE number="3">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>5678</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>BCA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<rdtime>123</rdtime>
</Node>
</SBD>
所需输出:
<SBD>
<DOCUMENT>
<Field1> value1</Field1>
</DOCUMENT>
<Node>
<ship>123</ship>
<field2>345r</field2>
<ITEM>
<IDENT>
<CODE>
<Value>67896789</Value>
</CODE>
</IDENT>
<LINE number="1">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>555</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>XYZ</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
</ITEM>
<ITEM>
<IDENT>
<CODE>
<Value>0870</Value>
</CODE>
</IDENT>
<LINE number="3">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>444</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>No</VALUE>
<TYPE>Key3</TYPE>
</FIER>
<FIER>
<VALUE>AAA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
</ITEM>
<ITEM>
<IDENT>
<CODE>
<Value>3243</Value>
</CODE>
</IDENT>
<LINE number="2">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>444</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>BBBB</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<Segment1>
<subsegment>
<value>123</value>
</subsegment>
</Segment1>
</ITEM>
<LINE number="1">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>6382</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>REA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<LINE number="3">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>5678</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>BCA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<LINE number="2">
<CIDENT>
<name>12</name>
<FIER>
<VALUE>5678</VALUE>
<TYPE>Key1</TYPE>
</FIER>
<FIER>
<VALUE>CBA</VALUE>
<TYPE>Key2</TYPE>
</FIER>
</CIDENT>
</LINE>
<rdtime>123</rdtime>
</Node>
</SBD>
我使用的XSLT如下:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Node">
<xsl:copy>
<xsl:for-each-group select="ITEM" group-by="LINE/CIDENT/FIER[TYPE='Key1']/VALUE">
<xsl:sequence select="sort(current-group(), (), function($l) { $l/LINE/CIDENT/FIER[TYPE='Key2']/VALUE })" />
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请审核一次
我认为,如果您知道要分组和/或排序的两个子元素,并且其他元素位于已知位置,您可以确保单独处理它们:
<xsl:template match="Node">
<xsl:copy>
<xsl:apply-templates select="* except (ITEM, LINE, rdtime)"/>
<xsl:for-each-group select="ITEM" group-by="LINE/CIDENT/FIER[TYPE='Key1']/VALUE">
<xsl:sequence select="sort(current-group(), (), function($l) { $l/LINE/CIDENT/FIER[TYPE='Key2']/VALUE })" />
</xsl:for-each-group>
<xsl:for-each-group select="LINE" group-by="CIDENT/FIER[TYPE='Key1']/VALUE">
<xsl:sequence select="sort(current-group(), (), function($l) { $l/CIDENT/FIER[TYPE='Key2']/VALUE })" />
</xsl:for-each-group>
<xsl:apply-templates select="rdtime"/>
</xsl:copy>
</xsl:template>