XSLT 分组为标题和位置

问题描述 投票:0回答:1

我有以下可用的 xml 导出:

<?xml version='1.0' encoding='UTF-8'?>
<document>
    <header>
        <creation-date>2022-08-09T08:46:00</creation-date>
        <SequenceOfDocument>10</SequenceOfDocument>
    </header>
    <businessobjects>
        <Reservation>
            <BeginDateTime>2022-07-29T16:00:00</BeginDateTime>
            <OrderNumber>606.00</OrderNumber>
            <Person>
                <UsrAddress>
                    <Code>0393</Code>
                </UsrAddress>
            </Person>
            <TotalActualCostExclVAT>30.00</TotalActualCostExclVAT>
            <ParentOrderRef/>
        </Reservation>
        <Reservation>
            <BeginDateTime>2022-07-29T16:00:00</BeginDateTime>
            <OrderNumber>606.01</OrderNumber>
            <RefBODefinitionUserDefined>UsrReservationEquipment</RefBODefinitionUserDefined>
            <Person>
                <UsrAddress>
                    <Code>0393</Code>
                </UsrAddress>
            </Person>
            <TotalActualCostExclVAT>40.00</TotalActualCostExclVAT>
            <ParentOrderRef>606.00</ParentOrderRef>
        </Reservation>
        
        <Reservation>
            <BeginDateTime>2022-07-29T16:00:00</BeginDateTime>
            <OrderNumber>607.00</OrderNumber>
            <RefBODefinitionUserDefined>UsrReservationEquipment</RefBODefinitionUserDefined>
            <Person>
                <UsrAddress>
                    <Code>0500</Code>
                </UsrAddress>
            </Person>
            <TotalActualCostExclVAT>50.00</TotalActualCostExclVAT>
            <ParentOrderRef></ParentOrderRef>
        </Reservation>
    </businessobjects>
</document>

我想通过 XSLT 进行所有操作,按以下方式分组:/Person/UsrAddress/Code

结果应该是:

<SalesOrderHeader>
    <SalesOrderHeaderFields>
        <CustomerNumber>0393</CustomerNumber>
    </SalesOrderHeaderFields>
    <ItemFields>
        <_USERFIELD1>606.00</_USERFIELD1>
    </ItemFields>
    <ItemFields>
        <_USERFIELD1>606.01</_USERFIELD1>
    </ItemFields>
</SalesOrderHeader>

<SalesOrderHeader>
    <SalesOrderHeaderFields>
        <CustomerNumber>0500</CustomerNumber>
    </SalesOrderHeaderFields>
    <ItemFields>
        <_USERFIELD1>607.00</_USERFIELD1>
    </ItemFields>
</SalesOrderHeader>

我已经尝试过:

<xsl:for-each-group select="Reservation" group-by="/Person/UsrAddress/Code">

                      <xsl:for-each select="current-group()">

但我没有将它们按人员/用户地址/代码分组。我不会像示例中那样将它们分组。也许有人可以给我提示?

xml xslt xslt-2.0
1个回答
-1
投票

这里有两种解决方案,一种使用

XSLT 1.0
,另一种使用
XSLT 2.0
基于您的标签

XSLT 2.0 解决方案

使用 xsl:for-each-group 指令。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="//document">
          <!-- Create SalesOrderHeader/SalesOrderHeaderFields/CustomerNumnber elements based on unique Person/UsrAddress/Code values -->
          <xsl:for-each-group select="businessobjects/Reservation" group-by="Person/UsrAddress/Code">
            <xsl:element name="SalesOrderHeader">
                <xsl:element name="SalesOrderHeaderFields">
                    <xsl:element name="CustomerNumber">
                        <xsl:value-of select="current-grouping-key()"/>
                    </xsl:element>
                </xsl:element>
                <!-- Create ItemFields/_USERFIELD1 elements grouped by Person/UsrAddress/Code values -->
                <xsl:for-each select="current-group()">
                    <xsl:element name="ItemFields">
                        <xsl:element name="_USERFIELD1">
                            <xsl:value-of select="OrderNumber" />
                        </xsl:element>
                    </xsl:element>
                </xsl:for-each>
            </xsl:element>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

参见 2.0 Fiddle

XSLT 1.0 解决方案

使用Muenchien Method进行分组。

<?xml version="1.0" encoding="UTF-8"?>
<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"/>
    <!-- Create Key based on the Code element -->
    <xsl:key name="unique-codes" match="//Reservation" use="Person/UsrAddress/Code" />
    <xsl:template match="//document">
        <!-- Create SalesOrderHeader/SalesOrderHeaderFields/CustomerNumnber elements based on unique Code values -->
        <xsl:for-each select="//Reservation[count(. | key('unique-codes', Person/UsrAddress/Code)[1]) = 1]">
            <xsl:sort select="Code" />
            <xsl:element name="SalesOrderHeader">
                <xsl:element name="SalesOrderHeaderFields">
                    <xsl:element name="CustomerNumber">
                        <xsl:value-of select="Person/UsrAddress/Code"/>
                    </xsl:element>
                </xsl:element>
                <!-- Create ItemFields/_USERFIELD1 elements grouped by unique Code values -->
                <xsl:for-each select="key('unique-codes', Person/UsrAddress/Code)">
                    <xsl:sort select="Code" />
                    <xsl:element name="ItemFields">
                        <xsl:element name="_USERFIELD1">
                            <xsl:value-of select="OrderNumber" />
                        </xsl:element>
                    </xsl:element>
                </xsl:for-each>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

参见 1.0 Fiddle

值得注意的是,要使其有效

XML
,您需要一个根标签来将其包装起来(即
<SalesOrders>
未包含在我的上述解决方案中,如下所示:

<SalesOrders>
    <SalesOrderHeader>
        <SalesOrderHeaderFields>
            <CustomerNumber>0393</CustomerNumber>
        </SalesOrderHeaderFields>
        <ItemFields>
            <_USERFIELD1>606.00</_USERFIELD1>
        </ItemFields>
        <ItemFields>
            <_USERFIELD1>606.01</_USERFIELD1>
        </ItemFields>
    </SalesOrderHeader>
    <SalesOrderHeader>
        <SalesOrderHeaderFields>
            <CustomerNumber>0500</CustomerNumber>
        </SalesOrderHeaderFields>
        <ItemFields>
            <_USERFIELD1>607.00</_USERFIELD1>
        </ItemFields>
    </SalesOrderHeader>
</SalesOrders>
© www.soinside.com 2019 - 2024. All rights reserved.