XSL muenchian-группировка на нескольких уровнях и вложенность - PullRequest
0 голосов
/ 09 мая 2018

INPUT:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<output>
    <queries>
        <query>
            <parameters>
                <parameter name="id">CTL-000002</parameter>
            </parameters>
            <queryResults>
                <record id="1">
                    <column name="ConfigurationCapacity">9500.0000000</column>
                    <column name="configurationCode">CTL-3819</column>
                    <column name="compartmentCode">CTL-3819-01</column>
                    <column name="position">1</column>
                    <column name="CompartmentCapacity">2700</column>
                    <column name="unitName">G</column>
                </record>
                <record id="2">
                    <column name="ConfigurationCapacity">52120.0000000</column>
                    <column name="configurationCode">CTL-3819</column>
                    <column name="compartmentCode">CTL-3819-01</column>
                    <column name="position">1</column>
                    <column name="CompartmentCapacity">22950</column>
                    <column name="unitName">K</column>
                </record>
                <record id="3">
                    <column name="ConfigurationCapacity">9500.0000000</column>
                    <column name="configurationCode">CTL-3819</column>
                    <column name="compartmentCode">CTL-3819-02</column>
                    <column name="position">2</column>
                    <column name="CompartmentCapacity">1700</column>
                    <column name="unitName">G</column>
                </record>
            </queryResults>
        </query>
    </queries>
</output>
<trailer>
    <id>CTL-000002</id>
    <trailer_tag>0</trailer_tag>
</trailer>
<output>
    <queries>
        <query>
            <parameters>
                <parameter name="id">3</parameter>
            </parameters>
            <queryResults>
                <record id="1">
                    <column name="ConfigurationCapacity">12</column>
                    <column name="configurationCode">LT</column>
                    <column name="compartmentCode">3819-01</column>
                    <column name="position">1</column>
                    <column name="CompartmentCapacity">70</column>
                    <column name="unitName">G</column>
                </record>
                <record id="2">
                    <column name="ConfigurationCapacity">500</column>
                    <column name="configurationCode">LT</column>
                    <column name="compartmentCode">3819-01</column>
                    <column name="position">1</column>
                    <column name="CompartmentCapacity">20</column>
                    <column name="unitName">K</column>
                </record>
            </queryResults>
        </query>
    </queries>
</output>
<trailer>
    <id>3</id>
    <trailer_tag>0</trailer_tag>
</trailer>
</root>

XSL:

  <xsl:key name="queries" match="root/output/queries/query/queryResults/record" use="./column[@name='compartmentCode']"/>
<xsl:template match="@* | node()">
    <xsl:variable name="uniqueCompartment" select="//record[string(column[@name='compartmentCode'])][count(. | key('queries', column[@name='compartmentCode'])[1]) = 1]"/>
    <root>
        <xsl:for-each select="//trailer">
            <xsl:choose>
                <xsl:when test="trailer_tag='0'">
                    <configurations>
                        <configuration>
                            <id>
                                <xsl:value-of select="//root/output/queries/query[parameters/parameter[@name='id'] = current()/id]/queryResults/record/column[@name='configurationCode']"/>
                            </id>
                            <compartments>
                                <!--I need to build the following structure for each unique compartmentCode-->
                                <xsl:for-each select="//root/output/queries/query/queryResults/record/column[@name='compartmentCode'][not(.=preceding::*)]">
                                    <compartment>
                                        <code>
                                            <xsl:value-of select="."/>
                                        </code>
                                        <capacities>
                                            <xsl:for-each select="$uniqueCompartment">
                                                <capacity>
                                                    <!--I need for each unique Compartment to build the unit node for each unique UNIT that specific record has, and another node with the value of compartmentCapacity of that UNIT-->
                                                    <unit>
                                                    </unit>
                                                    <val>
                                                    </val>
                                                </capacity>
                                            </xsl:for-each>
                                        </capacities>
                                    </compartment>
                                </xsl:for-each>
                            </compartments>
                        </configuration>
                    </configurations>
                    <!--copy  trailer node-->
                    <xsl:copy-of select="."/>
                </xsl:when>
                <xsl:otherwise>
                    <!--something else-->
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </root>
    </xsl:template>

желаемый выход:

<root>
<trailer>
    <id>CTL-000002</id>
    <trailer_tag>0</trailer_tag>
    <configurations>
        <configuration>
            <id>CTL-3819</id>
            <compartments>
                <compartment>
                    <code>CTL-3819-01</code>
                    <capacities>
                        <capacity>
                            <unit>G</unit>
                            <val>2700</val>
                        </capacity>
                        <capacity>
                            <unit>KG</unit>
                            <val>22950</val>
                        </capacity>
                    </capacities>
                </compartment>
                <compartment>
                    <code>CTL-3819-02</code>
                    <capacities>
                        <capacity>
                            <unit>G</unit>
                            <val>1700</val>
                        </capacity>
                    </capacities>
                </compartment>
            </compartments>
        </configuration>
    </configurations>
</trailer>
<trailer>
    <id>3</id>
    <trailer_tag>0</trailer_tag>
    <configurations>
        <configuration>
            <id>LT</id>
            <compartments>
                <compartment>
                    <code>3819-01</code>
                    <capacities>
                        <capacity>
                            <unit>G</unit>
                            <val>70</val>
                        </capacity>
                        <capacity>
                            <unit>K</unit>
                            <val>20</val>
                        </capacity>
                    </capacities>
                </compartment>
            </compartments>
        </configuration>
    </configurations>
</trailer>
</root>

Я попытался прочесть кое-что о мюнхенской группировке, но, похоже, не смог преодолеть эту точку. Чего я хочу достичь, это:

  1. для каждого уникального TRAILER / ID, скопируйте весь этот узел в выводе
  2. ЕСЛИ у трейлера / идентификатора есть узел запроса с тем же параметром / идентификатором, затем скопируйте трейлерный узел и соберите внутри него узел конфигурации, используя следующие правила:

    • configuration / ID - заполните этот тег значением из 'configurationCode' (это уникально для запроса)
    • для каждого уникального значения «cellCode »из запроса, построить узел отделения
      • для каждого кода купе может быть указано одно или несколько значений «unitNames» и «partCapacity ». Я хочу построить отдельные узлы с каждым значением, как показано в желаемом выводе.

Я далек от этого результата, но, пожалуйста, если кто-нибудь может мне помочь

Спасибо.

1 Ответ

0 голосов
/ 10 мая 2018

Вам нужен составной ключ здесь, так как вы хотите, чтобы различные значения compartmentCode находились в контексте configurationCode, поэтому ваш ключ будет выглядеть следующим образом

<xsl:key name="queries" 
         match="record" 
         use="concat(column[@name='configurationCode'], '|', column[@name='compartmentCode'])"/>

Затем, в течение query, чтобы получить уникальные значения CoNCode, сделайте это ...

<xsl:for-each 
     select="queryResults/record[generate-id() = generate-id(key('queries', concat(column[@name='configurationCode'], '|', column[@name='compartmentCode']))[1])]">

Попробуйте это (обратите внимание, как я разделил некоторый код в шаблон, соответствующий query, чтобы избежать слишком большого вложения кода и упростить некоторые xpaths)

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

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

<xsl:key name="queries" match="record" use="concat(column[@name='configurationCode'], '|', column[@name='compartmentCode'])"/>

<xsl:template match="/">
    <root>
        <xsl:for-each select="//trailer">
            <xsl:choose>
                <xsl:when test="trailer_tag='0'">
                    <xsl:copy>
                        <!--copy  trailer node-->
                        <xsl:copy-of select="@*|node()"/>
                        <xsl:apply-templates select="//root/output/queries/query[parameters/parameter[@name='id'] = current()/id]" />
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <!--something else-->
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </root>
</xsl:template>

<xsl:template match="query">
    <configurations>
        <configuration>
            <id>
                <xsl:value-of select="queryResults/record/column[@name='configurationCode']"/>
            </id>
            <compartments>
                <!--I need to build the following structure for each unique compartmentCode-->
                <xsl:for-each select="queryResults/record[generate-id() = generate-id(key('queries', concat(column[@name='configurationCode'], '|', column[@name='compartmentCode']))[1])]">
                    <compartment>
                        <code>
                            <xsl:value-of select="column[@name='compartmentCode']"/>
                        </code>
                        <capacities>
                            <xsl:for-each select="key('queries', concat(column[@name='configurationCode'], '|', column[@name='compartmentCode']))">
                                <capacity>
                                    <unit>
                                        <xsl:value-of select="column[@name='unitName']"/>
                                    </unit>
                                    <val>
                                        <xsl:value-of select="column[@name='CompartmentCapacity']"/>
                                    </val>
                                </capacity>
                            </xsl:for-each>
                        </capacities>
                    </compartment>
                </xsl:for-each>
            </compartments>
        </configuration>
    </configurations>    
</xsl:template>

</xsl:stylesheet>
...