微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

分组时如何删除空?

如何解决分组时如何删除空?

利用来自 https://stackoverflow.com/a/67741552/11928194 的知识,我想出了以下 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(预期#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) 开始:

如果 group-starting-with 属性存在,那么它的值必须 成为一种模式。

总体中的项目按总体顺序进行检查。如果 item 匹配模式,或者是群体中的第一个项目,然后 创建一个新组,该项目成为其第一个成员。 否则,该项目将被附加到与其前一个相同的组中 总体中的项目。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。