我在对段进行排序时遇到问题,我需要分别对段 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 documentStatus="True" date="2024-09-27">
<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>
<advice>123</advice>
<newfield>213</newfield>
</Node>
</SBD>
期望输出:
<SBD>
<DOCUMENT>
<Field1> value1</Field1>
</DOCUMENT>
<Node documentStatus="True" date="2024-09-27">
<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>
<advice>123</advice>
<newfield>213</newfield>
</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: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,advice,newfield"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请检查一次
我认为如果您知道要分组和/或排序的两个子元素,并且其他元素处于已知位置,那么您只需确保分别处理它们,当然您可以将模板应用于 Node 的属性: