XSLT2.0通过分组创建计数器

XSLT2.0通过分组创建计数器,xslt,group-by,count,sequence,edi,Xslt,Group By,Count,Sequence,Edi,我正在尝试为分组元素创建一个计数器 资料来源: <?xml version="1.0" encoding="UTF-8"?> <root_com> <root_por-out> <is_globalprocessid>1370284</is_globalprocessid> <is_processid>1370284</is_process

我正在尝试为分组元素创建一个计数器

资料来源:

<?xml version="1.0" encoding="UTF-8"?>
<root_com>
    <root_por-out>
        <is_globalprocessid>1370284</is_globalprocessid>
        <is_processid>1370284</is_processid>
        <partneridentcode>123456</partneridentcode>
        <por-out>
            <por_number>320060916</por_number>
            <order_pos>10</order_pos>
            <order_pos_partner>10</order_pos_partner>
        </por-out>
        <por-out>
            <por_number>320060916</por_number>
            <order_number_partner>875421</order_number_partner>
            <order_pos>20</order_pos>
            <order_pos_partner>20</order_pos_partner>
        </por-out>
        <por-out>
            <por_number>320060916</por_number>
            <order_pos>30</order_pos>
            <order_pos_partner>10</order_pos_partner>
        </por-out>
                <por-out>
            <por_number>320060916</por_number>
            <order_pos>40</order_pos>
            <order_pos_partner>30</order_pos_partner>
        </por-out>
        <por-out>
            <por_number>320060916</por_number>
            <order_pos>50</order_pos>
            <order_pos_partner>10</order_pos_partner>
        </por-out>
    </root_por-out>
</root_com>

1370284
1370284
123456
320060916
10
10
320060916
875421
20
20
320060916
30
10
320060916
40
30
320060916
50
10
期望输出:

<Confirmation>
    <Settings>
        <DecimalSymbol>.</DecimalSymbol>
    </Settings>
    <Orders>
        <Order>
            <OrderIdSupplier>320060916</OrderIdSupplier>
            <OrderItems>
                <OrderItem>
                    <LineNumber>10</LineNumber>
                    <ItemSubNo>1</ItemSubNo>
                </OrderItem>
                <OrderItem>
                    <LineNumber>20</LineNumber>
                    <ItemSubNo>1</ItemSubNo>
                </OrderItem>
                <OrderItem>
                    <LineNumber>10</LineNumber>
                    <ItemSubNo>2</ItemSubNo>
                </OrderItem>
                <OrderItem>
                    <LineNumber>30</LineNumber>
                    <ItemSubNo>1</ItemSubNo>
                </OrderItem>
                <OrderItem>
                    <LineNumber>10</LineNumber>
                    <ItemSubNo>3</ItemSubNo>
                </OrderItem>
            </OrderItems>
        </Order>
    </Orders>
</Confirmation>

.
320060916
10
1.
20
1.
10
2.
30
1.
10
3.
我目前拥有的代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:formatter="com.inubit.ibis.xsltext.Formatter" version="2.0" exclude-result-prefixes="formatter">
  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:template match="/"><xsl:for-each select="root_com/root_por-out"><Confirmation>
    <Settings>
        <DecimalSymbol>.</DecimalSymbol>
    </Settings>
    <Orders>
        <Order>
            <PurchaseNo><xsl:value-of select="por-out[1]/order_number_partner"/></PurchaseNo>
            <SupplierId><xsl:value-of select="partneridentcode"/></SupplierId>
            <OrderIdSupplier><xsl:value-of select="por-out[1]/por_number"/></OrderIdSupplier>
            <OrderItems><xsl:for-each select="por-out/order_pos"><xsl:for-each-group select="../order_pos_partner" group-by="text()"><OrderItem>
                    <DeliveryDate><xsl:value-of select="delivery_date"/></DeliveryDate>
                                <LineNumber><xsl:value-of select="current-grouping-key()"/></LineNumber><ItemSubNo><xsl:value-of select="last()"/></ItemSubNo>
                    <ProductId><xsl:value-of select="article_partner"/></ProductId>
                    <Price><xsl:value-of select="price"/></Price>
                    <PriceFactor>1</PriceFactor>
                    <Quantity><xsl:value-of select="quantity"/></Quantity>
                </OrderItem></xsl:for-each-group></xsl:for-each>
                
            </OrderItems>
        </Order>
    </Orders>
</Confirmation></xsl:for-each></xsl:template>
</xsl:stylesheet>

.
1.
代码简化为核心问题:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:formatter="com.inubit.ibis.xsltext.Formatter" version="2.0" exclude-result-prefixes="formatter">
  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:template match="/"><xsl:for-each select="root_com/root_por-out"><Confirmation>
    <Settings>
        <DecimalSymbol>.</DecimalSymbol>
    </Settings>
    <Orders>
        <Order>
            <OrderItems><xsl:for-each select="por-out/order_pos"><xsl:for-each-group select="../order_pos_partner" group-by="text()"><OrderItem>
                        <LineNumber><xsl:value-of select="current-grouping-key()"/></LineNumber><ItemSubNo><xsl:value-of select="last()"/></ItemSubNo>
                </OrderItem></xsl:for-each-group></xsl:for-each>
                
            </OrderItems>
        </Order>
    </Orders>
</Confirmation></xsl:for-each></xsl:template>
</xsl:stylesheet>

.
重点是: 客户发送订单。我们会作出回应。由于订购量很大,我们需要在不同日期交付订购的零件。我们分开了原来的位置。 在我们的回复中,客户获得了对其原始订单位置(订单位置合作伙伴)的参考,并且客户还需要一个计数器来计算拆分位置的数量(目的地:“ItemSubNo”)

我该怎么做

如果输出是按位置排序的,这很好,但不是必需的

如果您使用

  <xsl:template match="root_por-out">
    <Confirmation>
        <Orders>
          <Order>
            <OrderIdSupplier>{por-out[1]/por_number}</OrderIdSupplier>
            <xsl:for-each-group select="por-out" group-by="order_pos_partner">
              <xsl:apply-templates select="current-group()"/>
            </xsl:for-each-group>
          </Order>
        </Orders>
    </Confirmation>
  </xsl:template>

  <xsl:template match="por-out">
    <OrderItem>
      <LineNumber>{current-grouping-key()}</LineNumber>
      <ItemSubNumber>{position()}</ItemSubNumber>
    </OrderItem>    
  </xsl:template>

{por out[1]/por_number}
{current-grouping-key()}
{position()}
你会得到

        <OrderItem>
           <LineNumber>10</LineNumber>
           <ItemSubNumber>1</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>10</LineNumber>
           <ItemSubNumber>2</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>10</LineNumber>
           <ItemSubNumber>3</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>20</LineNumber>
           <ItemSubNumber>1</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>30</LineNumber>
           <ItemSubNumber>1</ItemSubNumber>
        </OrderItem> 

10
1.
10
2.
10
3.
20
1.
30
1.
因此,我认为这是正确的数字,尽管不是您显示的顺序

要保留原始输入顺序,您可以仅使用分组来存储正确的序列,然后再映射:

  <xsl:template match="root_por-out">
    <Confirmation>
        <Orders>
          <Order>
            <OrderIdSupplier>{por-out[1]/por_number}</OrderIdSupplier>
            <xsl:variable name="groups" as="map(*)">
              <xsl:map>
                <xsl:for-each-group select="por-out" group-by="order_pos_partner">
                  <xsl:map-entry key="current-grouping-key()" select="current-group() ! generate-id()"/>
                </xsl:for-each-group>                
              </xsl:map>
            </xsl:variable>
            <xsl:apply-templates select="*">
              <xsl:with-param name="groups" select="$groups"/>
            </xsl:apply-templates>
          </Order>
        </Orders>
    </Confirmation>
  </xsl:template>
  
  <xsl:template match="por-out">
    <xsl:param name="groups"/>
    <OrderItem>
      <LineNumber>{order_pos_partner}</LineNumber>
      <ItemSubNumber>{index-of($groups(order_pos_partner), generate-id())}</ItemSubNumber>
    </OrderItem>    
  </xsl:template>

{por out[1]/por_number}
{订单位置合作伙伴}
{($groups(order\u pos\u partner)的索引,generate-id())}
这两个示例都使用XSLT 3,但更详细(
{order\u pos\u partner}
而不是
或XML数据结构而不是轻量级映射

  <xsl:key name="group" match="group" use="@key"/>
  
  <xsl:template match="root_por-out">
    <Confirmation>
        <Orders>
          <Order>
            <OrderIdSupplier>{por-out[1]/por_number}</OrderIdSupplier>
            <xsl:variable name="groups">
                <xsl:for-each-group select="por-out" group-by="order_pos_partner">
                  <group key="{current-grouping-key()}">
                    <xsl:for-each select="current-group()">
                      <item>
                        <xsl:value-of select="generate-id()"/>
                      </item>
                    </xsl:for-each>
                  </group>
                </xsl:for-each-group>                
            </xsl:variable>
            <xsl:apply-templates select="*">
              <xsl:with-param name="groups" select="$groups"/>
            </xsl:apply-templates>
          </Order>
        </Orders>
    </Confirmation>
  </xsl:template>
  
  <xsl:template match="por-out">
    <xsl:param name="groups"/>
    <OrderItem>
      <LineNumber>
        <xsl:value-of select="order_pos_partner"/>
      </LineNumber>
      <ItemSubNumber>
        <xsl:value-of select="index-of(key('group', order_pos_partner, $groups)/item, generate-id())"/>
      </ItemSubNumber>
    </OrderItem>    
  </xsl:template>

{por out[1]/por_number}
它可以在XSLT2中完成。

如果您使用

  <xsl:template match="root_por-out">
    <Confirmation>
        <Orders>
          <Order>
            <OrderIdSupplier>{por-out[1]/por_number}</OrderIdSupplier>
            <xsl:for-each-group select="por-out" group-by="order_pos_partner">
              <xsl:apply-templates select="current-group()"/>
            </xsl:for-each-group>
          </Order>
        </Orders>
    </Confirmation>
  </xsl:template>

  <xsl:template match="por-out">
    <OrderItem>
      <LineNumber>{current-grouping-key()}</LineNumber>
      <ItemSubNumber>{position()}</ItemSubNumber>
    </OrderItem>    
  </xsl:template>

{por out[1]/por_number}
{current-grouping-key()}
{position()}
你会得到

        <OrderItem>
           <LineNumber>10</LineNumber>
           <ItemSubNumber>1</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>10</LineNumber>
           <ItemSubNumber>2</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>10</LineNumber>
           <ItemSubNumber>3</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>20</LineNumber>
           <ItemSubNumber>1</ItemSubNumber>
        </OrderItem>
        <OrderItem>
           <LineNumber>30</LineNumber>
           <ItemSubNumber>1</ItemSubNumber>
        </OrderItem> 

10
1.
10
2.
10
3.
20
1.
30
1.
因此,我认为这是正确的数字,尽管不是您显示的顺序

要保留原始输入顺序,您可以仅使用分组来存储正确的序列,然后再映射:

  <xsl:template match="root_por-out">
    <Confirmation>
        <Orders>
          <Order>
            <OrderIdSupplier>{por-out[1]/por_number}</OrderIdSupplier>
            <xsl:variable name="groups" as="map(*)">
              <xsl:map>
                <xsl:for-each-group select="por-out" group-by="order_pos_partner">
                  <xsl:map-entry key="current-grouping-key()" select="current-group() ! generate-id()"/>
                </xsl:for-each-group>                
              </xsl:map>
            </xsl:variable>
            <xsl:apply-templates select="*">
              <xsl:with-param name="groups" select="$groups"/>
            </xsl:apply-templates>
          </Order>
        </Orders>
    </Confirmation>
  </xsl:template>
  
  <xsl:template match="por-out">
    <xsl:param name="groups"/>
    <OrderItem>
      <LineNumber>{order_pos_partner}</LineNumber>
      <ItemSubNumber>{index-of($groups(order_pos_partner), generate-id())}</ItemSubNumber>
    </OrderItem>    
  </xsl:template>

{por out[1]/por_number}
{订单位置合作伙伴}
{($groups(order\u pos\u partner)的索引,generate-id())}
这两个示例都使用XSLT 3,但更详细(
{order\u pos\u partner}
而不是
或XML数据结构而不是轻量级映射

  <xsl:key name="group" match="group" use="@key"/>
  
  <xsl:template match="root_por-out">
    <Confirmation>
        <Orders>
          <Order>
            <OrderIdSupplier>{por-out[1]/por_number}</OrderIdSupplier>
            <xsl:variable name="groups">
                <xsl:for-each-group select="por-out" group-by="order_pos_partner">
                  <group key="{current-grouping-key()}">
                    <xsl:for-each select="current-group()">
                      <item>
                        <xsl:value-of select="generate-id()"/>
                      </item>
                    </xsl:for-each>
                  </group>
                </xsl:for-each-group>                
            </xsl:variable>
            <xsl:apply-templates select="*">
              <xsl:with-param name="groups" select="$groups"/>
            </xsl:apply-templates>
          </Order>
        </Orders>
    </Confirmation>
  </xsl:template>
  
  <xsl:template match="por-out">
    <xsl:param name="groups"/>
    <OrderItem>
      <LineNumber>
        <xsl:value-of select="order_pos_partner"/>
      </LineNumber>
      <ItemSubNumber>
        <xsl:value-of select="index-of(key('group', order_pos_partner, $groups)/item, generate-id())"/>
      </ItemSubNumber>
    </OrderItem>    
  </xsl:template>

{por out[1]/por_number}

这可以在XSLT 2中完成。

主题听起来好像要使用
count(current-group())
在某个地方,否则我还不明白您想要什么,发布的XSLT似乎创建了许多您在想要的输出中没有显示的元素,并且由于缺少缩进,很难判断您在那里尝试做什么。我缩短了输入和输出以备下注