xml - XSL 1.0 分组

标签 xml xslt xslt-1.0

我需要一些帮助。我对这种转变感到绝望。我必须使用 XSLT 1.0。

我有这个输入:

<?xml version="1.0" encoding="utf-8" ?>
<export>
    <ds>
        <cds>
            <cd id_c="1">
                <cs id="123" >
                    <acc>
                        <payments>
                            <payment id_p="9" price="6.90"/>
                        </payments>
                    </acc>
                    <acc>
                        <payments>
                            <payment id_p="9" price="6.50"/>
                        </payments>
                    </acc>
                </cs>
            </cd>
            <cd id_c="2">
                <cs id="456" >
                    <acc>
                        <payments>
                            <payment id_p="1" price="4.30"/>
                        </payments>
                    </acc>
                    <acc>
                        <payments>
                            <payment id_p="9" price="11.20"/>
                        </payments>
                    </acc>
                    <acc>
                        <payments>
                            <payment id_p="1" price="2.10"/>
                        </payments>
                    </acc>
                </cs>
            </cd>
            <cd id_c="3">
                <cs id="789" >
                    <acc>
                        <payments>
                            <payment id_p="2" price="8.90"/>
                        </payments>
                    </acc>
                    <acc>
                        <payments>
                            <payment id_p="9" price="5.70"/>
                        </payments>
                    </acc>
                </cs>
            </cd>           
        </cds>
    </ds>
</export>

我创造了这个转变

    <xsl:key name="group_payment" match="acc/payments" use="payment/@id_p"/>

    <xsl:template match="export">
    <document>
      <xsl:for-each select=".//ds/cds/cd">
            <record>
                <header>
                    <number><xsl:value-of select=".//@id" /></number>
                </header>
                <items>
                    <xsl:for-each select=".//payments[generate-id(.)=generate-id(key('group_payment', payment/@id_p))]/payment/@id_p">
                    <xsl:sort select="." order="ascending" case-order="lower-first" />
                    <item>
                        <text>Payment ID: <xsl:value-of select="."/></text>
                        <price><xsl:value-of select="sum(key('group_payment', .)//@price)"/></price>
                    </item>
                    </xsl:for-each>
                </items>
            </record>

        </xsl:for-each>
    </document>
    </xsl:template>

但这对我来说效果不佳。它将每笔付款分组为“第一匹配”。我需要在每个 payment/@id_p 元素内按 <cd> 对付款进行分组。

这是我的输出:

<?xml version="1.0" encoding="utf-8"?>
<document>
    <record>
        <header>
            <number>123</number>
        </header>
        <items>
            <item>
                <text>Payment ID: 9</text>
                <price>30.3</price>
            </item>
        </items>
    </record>
    <record>
        <header>
            <number>456</number>
        </header>
        <items>
            <item>
                <text>Payment ID: 1</text>
                <price>6.4</price>
            </item>
        </items>
    </record>
    <record>
        <header>
            <number>789</number>
        </header>
        <items>
            <item>
                <text>Payment ID: 2</text>
                <price>8.9</price>
            </item>
        </items>
    </record>
</document>

我想要这个输出:

<?xml version="1.0" encoding="utf-8"?>
<document>
    <record>
        <header>
            <number>123</number>
        </header>
        <items>
            <item>
                <text>Payment ID: 9</text>
                <price>13.40</price>
            </item>
        </items>
    </record>
    <record>
        <header>
            <number>456</number>
        </header>
        <items>
            <item>
                <text>Payment ID: 1</text>
                <price>6.40</price>
            </item>
            <item>
                <text>Payment ID: 9</text>
                <price>11.20</price>
            </item>
            </items>
    </record>
    <record>
        <header>
            <number>789</number>
        </header>
        <items>
            <item>
                <text>Payment ID: 2</text>
                <price>8.90</price>
            </item>
            <item>
                <text>Payment ID: 9</text>
                <price>5.70</price>
            </item>
        </items>
    </record>
</document>

我尝试了不同的分组,但总是以相同的结果结束。有人可以帮我吗?

最佳答案

AFAICT,你想做的事:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="pmt" match="payment" use="concat(@id_p, '|', ancestor::cs/@id)"/>

<xsl:template match="export">
    <document>
        <xsl:for-each select="ds/cds/cd/cs">
            <xsl:variable name="cs_id" select="@id" />
            <record>
                <header>
                    <number>
                        <xsl:value-of select="$cs_id" />
                    </number>
                </header>
                <items>
                    <xsl:for-each select="acc/payments/payment[generate-id() = generate-id(key('pmt', concat(@id_p, '|', $cs_id))[1])]">
                        <item>
                            <text>
                                <xsl:text>Payment ID: </xsl:text>
                                <xsl:value-of select="@id_p"/>
                            </text>
                            <price>
                                <xsl:value-of select="sum(key('pmt', concat(@id_p, '|', $cs_id))/@price)"/>
                            </price>
                        </item>
                    </xsl:for-each>
                </items>
            </record>
        </xsl:for-each>
    </document>
</xsl:template>

</xsl:stylesheet>

关于xml - XSL 1.0 分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72630935/

相关文章:

android - 如何在设置 View 的 alpha 之前创建 1 秒的延迟?

Python Pandas : use map function on iterator

c# - 来自 WebService 的未经净化的 XML,如何净化

java - org.apache.xalan.processor.TransformerFactoryImpl 上的 AbstractMethodError

xml - 使用 local-name() 获取 XSLT 中的第一个子节点

java - 根据 XSLT 版本选择 XSLT 处理器

使用 JDOM/XML 创建 Java xml

xslt - 使用 Apache Xalan 对 XML 进行 XSLT 转换后,命名空间前缀丢失

jakarta-ee - 解析 XSL 文件时出错

XSLT 1.0 贪婪背包分组方法?