【问题标题】:Removing duplicate in XSLT for node having multiple value删除 XSLT 中具有多个值的节点的重复项
【发布时间】:2016-11-09 10:04:18
【问题描述】:

我有一个包含重复节点的示例 XML。具有以下温度代码的节点 1 和节点 3 以及 FAH 和 CC 中的两个值都是重复的。 行节点内的所有值都需要检查以将其称为重复节点

     <row>
                <attr name="temperatureCode">STORADE</attr>
                <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                </attrQualMany>
        </row>

此示例消息是

<document>
<party>
    <gtin>1000909090</gtin>
    <pos>
        <attrGroupMany name="temperatureInformation">
            <row>
                <attr name="temperatureCode">STORADE</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
            </row>
            <row>
                <attr name="temperatureCode">HANDLING</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
            </row>
            <row>
                <attr name="temperatureCode">STORADE</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
            </row>
            <row>
                <attr name="temperatureCode">DUMMY</attr>
                <attrQualMany name="temperature">
                    <value qual="FAH">10</value>
                    <value qual="CC">20</value>
                </attrQualMany>
            </row>
        </attrGroupMany>
    </pos>
</party>
</document>

当我应用下面的 XSLT 时,它可以工作并删除重复的节点。我使用的 XSLT 是

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

<xsl:output indent="yes"/>

<xsl:key name="dummy" match="row" use="concat(attr[@name = 'temperatureCode'], '-', attrQualMany/value/@qual)"/>


<xsl:template match="document"> 
    <CatalogItem>
        <RelationshipData>
            <Relationship>
                <RelationType>temperatureInformation_details</RelationType>  
                <RelatedItems>      
                    <xsl:for-each select="party/pos/attrGroupMany[@name ='temperatureInformation']/row[generate-id() = generate-id(key('dummy', concat(attr[@name = 'temperatureCode'], '-', attrQualMany/value/@qual) ))]">                        
                        <RelatedItem>
                            <xsl:attribute name="referenceKey">
                                <xsl:value-of select="concat('temperatureInformation_details','-',attr[@name='temperatureCode'],'-',attrQualMany/@name,'-',attrQualMany/value/@qual,'-',attrQualMany/value,'-', position()    )"/>
                            </xsl:attribute>
                        </RelatedItem>


                    </xsl:for-each>

                </RelatedItems>
            </Relationship>
        </RelationshipData>
    </CatalogItem>

</xsl:template> 

</xsl:stylesheet>           

但它只检查 attrQualMany name="temperature" 中的第一个值,而不是 attrQualMany 下的两个值。

如果示例消息如下,但它不起作用。它应该在输出中给我 4 条记录,但它给了我 3 条记录。

    <document>
    <party>
        <gtin>1000909090</gtin>
        <pos>
            <attrGroupMany name="temperatureInformation">
                <row>
                    <attr name="temperatureCode">STORADE</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        **<value qual="CC">20</value>**
                    </attrQualMany>
                </row>
                <row>
                    <attr name="temperatureCode">HANDLING</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                    </attrQualMany>
                </row>
                <row>
                    <attr name="temperatureCode">STORADE</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        **<value qual="CC">30</value>**
                    </attrQualMany>
                </row>
                <row>
                    <attr name="temperatureCode">DUMMY</attr>
                    <attrQualMany name="temperature">
                        <value qual="FAH">10</value>
                        <value qual="CC">20</value>
                    </attrQualMany>
                </row>
            </attrGroupMany>
        </pos>
    </party>
    </document>

正确的预期输出是

    <?xml version="1.0" encoding="UTF-8"?>
    <CatalogItem>
   <RelationshipData>
      <Relationship>
         <RelationType>temperatureInformation_details</RelationType>
         <RelatedItems>
            <RelatedItem referenceKey="temperatureInformation_details-STORADE-temperature-FAH-10-1" />      
            <RelatedItem referenceKey="temperatureInformation_details-HANDLING-temperature-FAH-10-2" />
            <RelatedItem referenceKey="temperatureInformation_details-STORADE-temperature-FAH-10-3" /> 
             <RelatedItem referenceKey="temperatureInformation_details-DUMMY-temperature-FAH-10-4" />

         </RelatedItems>
      </Relationship>
   </RelationshipData>
    </CatalogItem>

任何意见,请告诉我

【问题讨论】:

  • "当我应用下面的 XSLT 时,它可以工作" 不,它没有。您的 XSLT 无法编译。
  • 我已经更正了。抱歉,是复制粘贴问题

标签: xml xslt xslt-1.0 xslt-grouping


【解决方案1】:

如果要按三个值分组,则必须在键中显式枚举所有三个值:

<xsl:key name="grp" match="row" use="concat(attr[@name='temperatureCode'], '|', attrQualMany/value[@qual='FAH'], '|', attrQualMany/value[@qual='CC'])"/>

我怀疑这可以缩短为:

<xsl:key name="grp" match="row" use="concat(attr, '|', attrQualMany/value[@qual='FAH'], '|', attrQualMany/value[@qual='CC'])"/>

补充:

&lt;attrQualMany name="temperature"&gt;下的数据都可以改 对于质量及其价值。所以我不能硬编码来检查 qual="FAH" 或 qual="CC"。是否有任何通用方法而不对 vaues 进行硬编码。

如果 - 且仅当 - attrQualMany 的结构对于已处理文档中的所有行都相同,您可以将密钥定义为:

<xsl:key name="grp" match="row" use="concat(attr[@name='temperatureCode'], '|', attrQualMany[@name='temperature'])"/>

相同的结构”是指在每一行 attrQualMany 包含相同的 value 子级,具有相同的 qual 属性,以相同的顺序列出。

如果上述条件不成立,则必须分两个阶段处理文档:首先,将要分组的所有值连接成单个文本值;然后按级联值对结果节点集进行分组。

【讨论】:

  • 可以在 下更改 qual 及其值的数据。所以我不能硬编码来检查 qual="FAH" 或 qual="CC"。是否有任何通用方法而不对 vaues 进行硬编码。
  • @Victor,是否总是有相同的已知数量的value 元素?您是否只想按位置比较它们以识别重复项?
  • @Martin,value 中的元素数量可以不同。我想连接 节点之间所有元素的所有值,然后确定重复。
  • @Victor 问题是这样的:单个文档中的所有行是否都具有相同的 value 元素(在 attrQualMany 中),以相同的顺序列出(如在您的示例中,它们都有 FAH 后跟 CC,没有别的)?
  • 没有。顺序没有定义,甚至值也可以不同。样本值可以是 DUMMY1020 20
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多