XSLT 2.0 通过分组创建计数器
XSLT 2.0 create counter through grouping
我正在尝试为分组元素创建一个计数器。
来源:
<?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>
期望的输出:
<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>
我目前拥有的代码:
<?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>
代码缩减为核心问题:
<?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>
重点是什么:
客户发送订单。我们提供回应。由于订购量大,我们需要在不同的日期交付订购的零件。我们拆分原始位置。
在我们的回复中,客户得到了他的原始订单位置的参考(order_pos_partner),客户还需要一个用于计算拆分位置数量的计数器(目的地:“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>
你会得到
<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>
所以我认为数字是正确的,尽管不是您显示的顺序。
要保留原始输入顺序,您可以仅使用分组来存储正确的序列,然后再映射它们:
<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>
这两个示例都使用 XSLT 3,尽管更加冗长(<LineNumber>{order_pos_partner}</LineNumber>
而不是 <LineNumber><xsl:value-of select="current-grouping-key()"/></LineNumber>
或 XML 数据结构而不是 light-weight 映射
<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>
可以在 XSLT 2 中完成。
我正在尝试为分组元素创建一个计数器。
来源:
<?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>
期望的输出:
<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>
我目前拥有的代码:
<?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>
代码缩减为核心问题:
<?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>
重点是什么: 客户发送订单。我们提供回应。由于订购量大,我们需要在不同的日期交付订购的零件。我们拆分原始位置。 在我们的回复中,客户得到了他的原始订单位置的参考(order_pos_partner),客户还需要一个用于计算拆分位置数量的计数器(目的地:“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>
你会得到
<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>
所以我认为数字是正确的,尽管不是您显示的顺序。
要保留原始输入顺序,您可以仅使用分组来存储正确的序列,然后再映射它们:
<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>
这两个示例都使用 XSLT 3,尽管更加冗长(<LineNumber>{order_pos_partner}</LineNumber>
而不是 <LineNumber><xsl:value-of select="current-grouping-key()"/></LineNumber>
或 XML 数据结构而不是 light-weight 映射
<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>
可以在 XSLT 2 中完成。