Удаление дубликата в XSLT для узла с несколькими значениями

У меня есть образец 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="температура", а не оба значения в 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>

Любой вклад, пожалуйста, дайте мне знать

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'])"/>

Добавлено:

Данные могут быть изменены в <attrQualMany name="temperature"> как для квалификации, так и для ее стоимости. Поэтому я не могу жестко кодировать, чтобы проверить qual="FAH" или qual="CC". Есть ли какой-либо общий способ без жесткого кодирования Vaues.

Если - и только если - структура attrQualMany идентичен для всех строк в обработанном документе, вы можете определить свой ключ как:

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

Под "идентичной структурой" я подразумеваю, что в каждом ряду attrQualMany содержит то же самое value дети, с такими же qual атрибуты, перечисленные в том же порядке.

Если вышеприведенное условие неверно, вам придется обрабатывать документ в два этапа: во-первых, объединить все значения, по которым вы хотите сгруппировать одно текстовое значение; затем сгруппируйте полученный набор узлов по объединенному значению.

Другие вопросы по тегам