xslt для группировки xml на основе значений элементов - PullRequest
0 голосов
/ 06 июля 2018

хотите сгруппировать запрос на основе идентичного идентификатора пакета, используя XSLT вручную Вот входной XML, который содержит plan_id, по которому он должен быть сгруппирован

<subscriptions>
    <package>
        <package_plan>
            <plan_id>1111</plan_id>
            <plan_name>economy1</plan_name>
        </package_plan>
        <rate_channel>
            <rateid>1F1</rateid>
            <currency>USD</currency>
            <package_duration>monthly</package_duration>
            <price>3</price>
        </rate_channel>
    </package>
    <package>
        <package_plan>
            <plan_id>1111</plan_id>
            <plan_name>economy1</plan_name>
        </package_plan>
        <rate_channel>
            <rateid>1F2</rateid>
            <currency>USD</currency>
            <package_duration>quaterly</package_duration>
            <price>11</price>
        </rate_channel>
    </package>
    <package>
        <package_plan>
            <plan_id>2222</plan_id>
            <plan_name>economy2</plan_name>
        </package_plan>
        <rate_channel>
            <rateid>1F3</rateid>
            <currency>INR</currency>
            <package_duration>monthly</package_duration>
            <price>250</price>
        </rate_channel>
    </package>
</subscriptions>

Искать вывод как:

<subscriptions>
    <package>
        <plan_id>1111</plan_id>
        <plan_name>economy1</plan_name>
        <channels>
            <rate_channel>
                <rateid>1F1</rateid>
                <currency>USD</currency>
                <package_duration>monthly</package_duration>
                <price>3</price>
            </rate_channel>
            <rate_channel>
                <rateid>1F2</rateid>
                <currency>USD</currency>
                <package_duration>quaterly</package_duration>
                <price>11</price>
            </rate_channel>
        </channels>
    </package>
    <package>
        <plan_id>2222</plan_id>
        <plan_name>economy2</plan_name>
        <channels>
            <rate_channel>
                <rateid>1F3</rateid>
                <currency>INR</currency>
                <package_duration>monthly</package_duration>
                <price>250</price>
            </rate_channel>
        </channels>
    </package>
</subscriptions>

Я занимался поиском и чтением других постов, и я не думаю, что они охватывают именно то, что я хочу сделать Заранее спасибо ...

1 Ответ

0 голосов
/ 07 июля 2018

Ниже представлены решения XSLT 1.0 и XSLT 2.0. Оба решения используют различный подход, как справедливо указано @Tim C. в комментарии.

XSLT 1.0

В случае XSLT 1.0 используется muenchian группировка . <xsl:key> необходимо определить для группировки элементов. В этом случае <plan_id> - это ключ, по которому будет выполняться группировка.

<xsl:key name="plan" match="package" use="package_plan/plan_id" />

Элементы package сопоставляются соответствующим образом, и сгруппированные данные копируются в вывод.

<xsl:template match="package[generate-id() = generate-id(key('plan', package_plan/plan_id)[1])]">
    <xsl:copy>
        <xsl:variable name="varPlan" select="key('plan', package_plan/plan_id)" />
        <xsl:apply-templates select="$varPlan[1]/package_plan/plan_id" />
        <xsl:apply-templates select="$varPlan[1]/package_plan/plan_name" />
        <channels>
            <xsl:for-each select="$varPlan">
                <xsl:apply-templates select="rate_channel" />
            </xsl:for-each>
        </channels>
    </xsl:copy>
</xsl:template>

Остальные элементы <package> удалены.

<xsl:template match="package" />

XSLT 2.0

В XSLT 2.0 функция <xsl-for-each-group> доступна специально для группировки элементов. В этом случае, используя эту функцию и функцию current-group(), можно добиться группировки.

<xsl:template match="subscriptions">
    <xsl:copy>
        <xsl:for-each-group select="package" group-by="package_plan/plan_id">
            <package>
                <xsl:apply-templates select="current-group()[1]/package_plan/plan_id" />
                <xsl:apply-templates select="current-group()[1]/package_plan/plan_name" />
                <channels>
                    <xsl:for-each select="current-group()">
                        <xsl:apply-templates select="rate_channel" />
                    </xsl:for-each>
                </channels>
            </package>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

В обоих вышеупомянутых случаях следует использовать шаблон identity transform для копирования данных как есть.

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...