xslt удалить запись на основе критериев и groupBy - PullRequest
0 голосов
/ 31 января 2020

Я борюсь со сложным xsl-преобразованием и не могу понять, как заставить его работать. В качестве входных данных у меня есть коллекция записей. Каждая запись идентифицируется двумя ключами (pk1 и pk2) и имеет квалификатор. Цель состоит в том, чтобы скопировать записи, сгруппированные по pk1 и pk2. И это просто. Проблема возникает, когда мне приходится копировать только те, где вхождения квалификатора A и B совпадают. Вот входной файл.

<Data>
<!-- first case -->
<record>
    <pk1>0001</pk1>
    <pk2>AAA</pk2>
    <quantity>50.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- second case -->
<record>
    <pk1>0002</pk1>
    <pk2>AAA</pk2>
    <quantity>10.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0002</pk1>
    <pk2>AAA</pk2>
    <quantity>10.00</quantity>
    <qualifier>B</qualifier>
</record>
<record>
    <pk1>0002</pk1>
    <pk2>BBB</pk2>
    <quantity>15.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- third case -->
<record>
    <pk1>0003</pk1>
    <pk2>AAA</pk2>
    <quantity>20.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>AAA</pk2>
    <quantity>20.00</quantity>
    <qualifier>B</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>AAA</pk2>
    <quantity>20.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>BBB</pk2>
    <quantity>70.00</quantity>
    <qualifier>A</qualifier>
</record>
<record>
    <pk1>0003</pk1>
    <pk2>BBB</pk2>
    <quantity>70.00</quantity>
    <qualifier>B</qualifier>
</record>
<!-- fourth case -->
<record>
    <pk1>0004</pk1>
    <pk2>AAA</pk2>
    <quantity>100.00</quantity>
    <qualifier>B</qualifier>
</record>

И это ожидаемый результат.

<Data>
<!-- first case -->
<!-- second case -->
<record>
    <pk1>0002</pk1>
    <pk2>AAA</pk2>
    <quantity>10.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- third case -->
<record>
    <pk1>0003</pk1>
    <pk2>BBB</pk2>
    <quantity>70.00</quantity>
    <qualifier>A</qualifier>
</record>
<!-- fourth case -->

Объяснение для каждого случая: Первый случай: 0001 | AAA | A не имеет своей пары 0001 | AAA | B -> remove

Второй случай: 0002 | AAA | A имеет свою пару 0002 | AAA | B -> оставьте "A «один

третий случай: 0003 | AAA | A имеет свою пару 0003 | AAA | B, но есть еще один 0003 | AAA | A, что означает, что для этой группы« A »не являются одинаковыми вхождениями» B "s -> удалить

Третий случай: 0003 | BBB | A имеет свою пару 0003 | BBB | B -> оставить единицу" A "

Четвертый случай: 0004 | AAA | A не имеет своей пары 0004 | AAA | B -> remove

Как я уже сказал, я не знаю, как этого добиться, и можно ли это сделать с помощью xslt. Не могли бы вы мне помочь? Спасибо.

1 Ответ

0 голосов
/ 31 января 2020

Рассмотрим следующий упрощенный пример:

XML

<Data>
    <!-- first case -->
    <record>
        <group>0001</group>
        <quantity>50.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <!-- second case -->
    <record>
        <group>0002</group>
        <quantity>10.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <record>
        <group>0002</group>
        <quantity>11.00</quantity>
        <qualifier>B</qualifier>
    </record>
    <record>
        <group>0002</group>
        <quantity>12.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <record>
        <group>0002</group>
        <quantity>13.00</quantity>
        <qualifier>B</qualifier>
    </record>
    <!-- third case -->
    <record>
        <group>0003</group>
        <quantity>20.00</quantity>
        <qualifier>A</qualifier>
    </record>
    <record>
        <group>0003</group>
        <quantity>30.00</quantity>
        <qualifier>B</qualifier>
    </record>
    <record>
        <group>0003</group>
        <quantity>40.00</quantity>
        <qualifier>A</qualifier>
    </record>
</Data>

XSLT 2.0

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>

<xsl:template match="/Data">
    <Data>
        <xsl:for-each-group select="record" group-by="group">
            <xsl:if test="count(current-group()[qualifier='A'])=count(current-group()[qualifier='B'])">
                <record>
                    <xsl:copy-of select="group" />
                    <quantity>
                        <xsl:value-of select="sum(current-group()/quantity)" />
                    </quantity>
                </record>
            </xsl:if>
        </xsl:for-each-group>
    </Data>
</xsl:template>

</xsl:stylesheet>

Результат

<Data>
   <record>
      <group>0002</group>
      <quantity>46</quantity>
   </record>
</Data>

Демонстрация: https://xsltfiddle.liberty-development.net/pPJ9hEe

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...