分组时如何去除空?
How to remove empty when grouping?
利用来自 的知识,我提出了以下 XSLT:
<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json='http://james.newtonking.com/projects/json'
version="3.0">
<xsl:output omit-xml-declaration='yes' method='xml' version='1.0' />
<xsl:template match='/'>
<edi856>
<xsl:for-each-group select="/ns0:X12_00401_856/ns0:HLLoop1" group-starting-with="/ns0:X12_00401_856/ns0:HLLoop1[ns0:HL03='Q']">
<hlq json:Array='true'>
<hlqId>
<xsl:value-of select="current-group()/ns0:TSD/TSD01"/>
</hlqId>
<xsl:variable name="hlq" select="current-group()" />
<xsl:variable name="hlq-id" select="$hlq/ns0:TSD/TSD01" />
<xsl:for-each-group select="current-group()[position() gt 1]" group-starting-with="/ns0:X12_00401_856/ns0:HLLoop1[ns0:HL/HL03='I']">
<hli json:Array='true'>
<hlqId>
<xsl:value-of select="$hlq-id"/>
</hlqId>
<hliId>
<xsl:value-of select="current-group()/ns0:LIN/LIN03"/>
</hliId>
</hli>
</xsl:for-each-group>
</hlq>
</xsl:for-each-group>
</edi856>
</xsl:template>
</xsl:stylesheet>
当我将它与以下输入 (Input#1) 一起使用时:
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ns0:HLLoop1>
<ns0:HL>
<HL03>Q</HL03>
</ns0:HL>
<ns0:TSD>
<TSD01>DELIVERY1</TSD01>
</ns0:TSD>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL03>I</HL03>
</ns0:HL>
<ns0:LIN>
<LIN03>asnLineItem1</LIN03>
</ns0:LIN>
</ns0:HLLoop1>
</ns0:X12_00401_856>
输出生成为(实际#1):
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId/>
</hli>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId>asnLineItem1</hliId>
</hli>
</hlq>
</edi856>
我希望输出只有 1 hli
(Expected#1):
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId>asnLineItem1</hliId>
</hli>
</hlq>
</edi856>
当我删除 HL03=I 的 HLLLoop1 时,我希望 hli
不存在于输出中,但它仍然存在。
输入#2:
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ns0:HLLoop1>
<ns0:HL>
<HL03>Q</HL03>
</ns0:HL>
<ns0:TSD>
<TSD01>DELIVERY1</TSD01>
</ns0:TSD>
</ns0:HLLoop1>
</ns0:X12_00401_856>
实际#2:
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId/>
</hli>
</hlq>
</edi856>
预计#2:
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
</hlq>
</edi856>
我在这里缺少什么来满足我的期望?
也许将内部 for-each-group
的内容包装到 <xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='I']">...</xsl:if>
中会有所帮助,但我不确定我是否理解了输入数据的结构和所需的分组要求。
而且我认为对于外部 for-each-group
你宁愿 group-starting-with="ns0:HLLoop1[ns0:HL/HL03='Q']"
但你也需要将 for-each-group
的主体包装成 <xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='Q']">..</xsl:if>
以输出结果仅适用于匹配组,而不适用于 for-each-group
为您提供的不匹配项。
所以模板应该是
<xsl:template match='/'>
<edi856>
<xsl:variable name="bsn02" select="/ns0:X12_00401_856/ns0:BSN/BSN02" />
<xsl:for-each-group select="/ns0:X12_00401_856/ns0:HLLoop1" group-starting-with="ns0:HLLoop1[ns0:HL/HL03='Q']">
<xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='Q']">
<hlq json:Array='true'>
<hlqId>
<xsl:value-of select="current-group()/ns0:TSD/TSD01"/>
</hlqId>
<bsn02>
<xsl:value-of select="$bsn02"/>
</bsn02>
<xsl:variable name="hlq" select="current-group()" />
<xsl:variable name="hlq-id" select="$hlq/ns0:TSD/TSD01" />
<xsl:for-each-group select="current-group()[position() gt 1]" group-starting-with="ns0:HLLoop1[ns0:HL/HL03='I']">
<xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='I']">
<hli json:Array='true'>
<hlqId>
<xsl:value-of select="$hlq-id"/>
</hlqId>
<bsn02>
<xsl:value-of select="$bsn02"/>
</bsn02>
<hliId>
<xsl:value-of select="current-group()/ns0:LIN/LIN03"/>
</hliId>
</hli>
</xsl:if>
</xsl:for-each-group>
</hlq>
</xsl:if>
</xsl:for-each-group>
</edi856>
</xsl:template>
这些样本与前一个样本之间的区别在于,您的分组总体始终以匹配项目 (https://www.w3.org/TR/xslt-30/#xsl-for-each-group) 开始:
If the group-starting-with attribute is present, then its value must
be a pattern.
The items in the population are examined in population order. If an
item matches the pattern, or is the first item in the population, then
a new group is created and the item becomes its first member.
Otherwise, the item is appended to the same group as its preceding
item within the population.
利用来自
<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json='http://james.newtonking.com/projects/json'
version="3.0">
<xsl:output omit-xml-declaration='yes' method='xml' version='1.0' />
<xsl:template match='/'>
<edi856>
<xsl:for-each-group select="/ns0:X12_00401_856/ns0:HLLoop1" group-starting-with="/ns0:X12_00401_856/ns0:HLLoop1[ns0:HL03='Q']">
<hlq json:Array='true'>
<hlqId>
<xsl:value-of select="current-group()/ns0:TSD/TSD01"/>
</hlqId>
<xsl:variable name="hlq" select="current-group()" />
<xsl:variable name="hlq-id" select="$hlq/ns0:TSD/TSD01" />
<xsl:for-each-group select="current-group()[position() gt 1]" group-starting-with="/ns0:X12_00401_856/ns0:HLLoop1[ns0:HL/HL03='I']">
<hli json:Array='true'>
<hlqId>
<xsl:value-of select="$hlq-id"/>
</hlqId>
<hliId>
<xsl:value-of select="current-group()/ns0:LIN/LIN03"/>
</hliId>
</hli>
</xsl:for-each-group>
</hlq>
</xsl:for-each-group>
</edi856>
</xsl:template>
</xsl:stylesheet>
当我将它与以下输入 (Input#1) 一起使用时:
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ns0:HLLoop1>
<ns0:HL>
<HL03>Q</HL03>
</ns0:HL>
<ns0:TSD>
<TSD01>DELIVERY1</TSD01>
</ns0:TSD>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL03>I</HL03>
</ns0:HL>
<ns0:LIN>
<LIN03>asnLineItem1</LIN03>
</ns0:LIN>
</ns0:HLLoop1>
</ns0:X12_00401_856>
输出生成为(实际#1):
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId/>
</hli>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId>asnLineItem1</hliId>
</hli>
</hlq>
</edi856>
我希望输出只有 1 hli
(Expected#1):
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId>asnLineItem1</hliId>
</hli>
</hlq>
</edi856>
当我删除 HL03=I 的 HLLLoop1 时,我希望 hli
不存在于输出中,但它仍然存在。
输入#2:
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ns0:HLLoop1>
<ns0:HL>
<HL03>Q</HL03>
</ns0:HL>
<ns0:TSD>
<TSD01>DELIVERY1</TSD01>
</ns0:TSD>
</ns0:HLLoop1>
</ns0:X12_00401_856>
实际#2:
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hli json:Array="true">
<hlqId>DELIVERY1</hlqId>
<hliId/>
</hli>
</hlq>
</edi856>
预计#2:
<edi856 xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
xmlns:json="http://james.newtonking.com/projects/json">
<hlq json:Array="true">
<hlqId>DELIVERY1</hlqId>
</hlq>
</edi856>
我在这里缺少什么来满足我的期望?
也许将内部 for-each-group
的内容包装到 <xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='I']">...</xsl:if>
中会有所帮助,但我不确定我是否理解了输入数据的结构和所需的分组要求。
而且我认为对于外部 for-each-group
你宁愿 group-starting-with="ns0:HLLoop1[ns0:HL/HL03='Q']"
但你也需要将 for-each-group
的主体包装成 <xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='Q']">..</xsl:if>
以输出结果仅适用于匹配组,而不适用于 for-each-group
为您提供的不匹配项。
所以模板应该是
<xsl:template match='/'>
<edi856>
<xsl:variable name="bsn02" select="/ns0:X12_00401_856/ns0:BSN/BSN02" />
<xsl:for-each-group select="/ns0:X12_00401_856/ns0:HLLoop1" group-starting-with="ns0:HLLoop1[ns0:HL/HL03='Q']">
<xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='Q']">
<hlq json:Array='true'>
<hlqId>
<xsl:value-of select="current-group()/ns0:TSD/TSD01"/>
</hlqId>
<bsn02>
<xsl:value-of select="$bsn02"/>
</bsn02>
<xsl:variable name="hlq" select="current-group()" />
<xsl:variable name="hlq-id" select="$hlq/ns0:TSD/TSD01" />
<xsl:for-each-group select="current-group()[position() gt 1]" group-starting-with="ns0:HLLoop1[ns0:HL/HL03='I']">
<xsl:if test="self::ns0:HLLoop1[ns0:HL/HL03='I']">
<hli json:Array='true'>
<hlqId>
<xsl:value-of select="$hlq-id"/>
</hlqId>
<bsn02>
<xsl:value-of select="$bsn02"/>
</bsn02>
<hliId>
<xsl:value-of select="current-group()/ns0:LIN/LIN03"/>
</hliId>
</hli>
</xsl:if>
</xsl:for-each-group>
</hlq>
</xsl:if>
</xsl:for-each-group>
</edi856>
</xsl:template>
这些样本与前一个样本之间的区别在于,您的分组总体始终以匹配项目 (https://www.w3.org/TR/xslt-30/#xsl-for-each-group) 开始:
If the group-starting-with attribute is present, then its value must be a pattern.
The items in the population are examined in population order. If an item matches the pattern, or is the first item in the population, then a new group is created and the item becomes its first member. Otherwise, the item is appended to the same group as its preceding item within the population.