繁体   English   中英

在XSLT中与可选节点匹配并合并

[英]match and merge in XSLT with optional nodes

我有一个示例XML消息,其中包含多个父节点。 要求是,如果两个父节点相同,则合并子节点。 当所有节点都存在时,此方法工作正常,但在不存在可选节点时,则无效

样本消息:1带有可选节点

<document>
<body>
    <party>
        <gtin>1000909090</gtin>
        <pos>
            <attrGroupMany name="temperatureInformation">
                <row>
                    <gtin>1000909090</gtin>
                    <attr name="temperatureCode">STORAGE</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                    </attrQualMany>
                    <attrGroupMany name="temperatureStats">   <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE1</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE2</attr>
                        </row>
                    </attrGroupMany>
                </row>
                <row>
                    <attr name="temperatureCode">STORAGE</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                    </attrQualMany>
                    <attrGroupMany name="temperatureStats">    <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE3</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE4</attr>
                        </row>
                    </attrGroupMany>
                </row>
                <row>
                    <attr name="temperatureCode">HANDLING</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>                    
                    </attrQualMany>
                    <attrGroupMany name="temperatureStats">    <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE5</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE6</attr>
                        </row>
                    </attrGroupMany>
                </row>
                <row>
                    <attr name="temperatureCode">HANDLING</attr>
                    <attrGroupMany name="temperatureStats">      <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE7</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE8</attr>
                        </row>
                    </attrGroupMany>
                </row>
            </attrGroupMany>
        </pos>
    </party>    
</body>
</document>

下面的示例XSLT可以很好地从'attrGroupMany name =“ temperatureInformation”'中删除重复项

使用XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">



<xsl:key name="group" match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row"
    use="concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="row[generate-id() = generate-id(key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attrGroupMany[@name = 'temperatureStats']">
    <xsl:copy>
        <xsl:apply-templates select="@* | key('group', concat(generate-id(ancestor::pos), '|',../attr[@name = 'temperatureCode'], '|', ../attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

与以上XSLT不兼容的示例消息2是

<document>
<body>
    <party>
        <gtin>1000909090</gtin>
        <pos>
            <attrGroupMany name="temperatureInformation">
                <row>
                    <gtin>1000909090</gtin>
                    <attr name="temperatureCode">STORAGE</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                    </attrQualMany>
                </row>
                <row>
                    <attr name="temperatureCode">STORAGE</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                    </attrQualMany>
                    <attrGroupMany name="temperatureStats">    <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE3</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE4</attr>
                        </row>
                    </attrGroupMany>
                </row>
                <row>
                    <attr name="temperatureCode">HANDLING</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>                    
                    </attrQualMany>
                    <attrGroupMany name="temperatureStats">    <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE5</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE6</attr>
                        </row>
                    </attrGroupMany>
                </row>
                <row>
                    <attr name="temperatureCode">HANDLING</attr>
                    <attrGroupMany name="temperatureStats">      <!--  optional group -->
                        <row>
                            <attr name="StatsCode">CODE7</attr>
                        </row>
                        <row>
                            <attr name="StatsCode">CODE8</attr>
                        </row>
                    </attrGroupMany>
                </row>
            </attrGroupMany>
        </pos>
    </party>    
</body>
</document>

有人可以让我知道如何处理比赛n合并中的可选节点

示例消息2的预期输出为

<?xml version="1.0" encoding="UTF-8"?>
<document>
<body>
  <party>
     <gtin>1000909090</gtin>
     <pos>
        <attrGroupMany name="temperatureInformation">
           <row>
              <gtin>1000909090</gtin>
              <attr name="temperatureCode">STORAGE</attr>
              <attrQualMany name="temperature">
                 <value qual="FAH">10</value>
                 <value qual="CC">20</value>
              </attrQualMany>
              <attrGroupMany name="temperatureStats">                   
                 <row>
                    <attr name="StatsCode">CODE3</attr>
                 </row>
                 <row>
                    <attr name="StatsCode">CODE4</attr>
                 </row>
              </attrGroupMany>
           </row>
           <row>
              <attr name="temperatureCode">HANDLING</attr>
              <attrQualMany name="temperature">
                 <value qual="FAH">10</value>
              </attrQualMany>
              <attrGroupMany name="temperatureStats">
                 <row>
                    <attr name="StatsCode">CODE5</attr>
                 </row>
                 <row>
                    <attr name="StatsCode">CODE6</attr>
                 </row>
              </attrGroupMany>
           </row>
           <row>
              <attr name="temperatureCode">HANDLING</attr>
              <attrGroupMany name="temperatureStats">
                 <row>
                    <attr name="StatsCode">CODE7</attr>
                 </row>
                 <row>
                    <attr name="StatsCode">CODE8</attr>
                 </row>
              </attrGroupMany>
           </row>
        </attrGroupMany>
     </pos>
  </party>
</body>
</document>

有人可以让我知道如何在比赛n合并中处理可选节点。 谢谢

您尚未解释要执行的操作背后的逻辑,但是通过查看此问题以及以前的问题的XSLT,您可以将attrGroupMany[@name = 'temperatureInformation']/row元素分组,但是将祖先pos以及“ temperatureCode”和“ temperature”。

然后,对于每个这样的不同row ,您似乎都想添加所有<attrGroupMany name="temperatureStats">元素。 如果您说模板是可选的,那么与该元素匹配的模板将无法工作。 而是要有一个与父row匹配的模板,并使用该模板从键中的所有元素中选择所有子元素。

<xsl:template match="attrGroupMany[@name = 'temperatureInformation']/row">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[not(self::attrGroupMany[@name = 'temperatureStats'])]"/> 
        <attrGroupMany name="temperatureStats">
            <xsl:apply-templates select="key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
        </attrGroupMany>
    </xsl:copy>
</xsl:template>

我假设所有StatsCode在这里都是不同的。 如果可能有重复项,并且您想删除此类重复项,则需要在问题中这样说。

试试这个XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes" />

<xsl:key name="group" match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row"
    use="concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="row[generate-id() = generate-id(key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attrGroupMany[@name = 'temperatureInformation']/row">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[not(self::attrGroupMany[@name = 'temperatureStats'])]"/> 
        <attrGroupMany name="temperatureStats">
            <xsl:apply-templates select="key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
        </attrGroupMany>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    version="1.0">

<xsl:output method="xml" indent="yes" />

<xsl:key name="grouptemperatureInformation" match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row"
use="concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>

<xsl:key name="grouptemperatureStats" 
         match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row/attrGroupMany[@name = 'temperatureStats']/row"
         use="concat(generate-id(ancestor::pos), '|', ../../../attr[@name = 'temperatureCode'], '|', ../../../attrQualMany[@name = 'temperature'], '|', attr[@name = 'StatsCode'])"/>


<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="row[generate-id() = generate-id(key('grouptemperatureInformation', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attrGroupMany[@name = 'temperatureInformation']/row">
    <xsl:variable name="group" select="key('grouptemperatureInformation', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))/attrGroupMany[@name='temperatureStats']/row" />
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[not(self::attrGroupMany[@name = 'temperatureStats'])]"/> 
        <attrGroupMany name="temperatureStats">             
            <xsl:apply-templates select="@* | $group[generate-id() = generate-id(key('grouptemperatureStats', concat(generate-id(ancestor::pos), '|', ../../../attr[@name = 'temperatureCode'], '|', ../../../attrQualMany[@name = 'temperature'], '|', attr[@name = 'StatsCode']))[1])]"/> 
        </attrGroupMany>
    </xsl:copy>
 </xsl:template>
 </xsl:stylesheet>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM