根据包含子实体的元素值合并 XML 条消息
Combine XML Messages based on element value including sub-entities
我需要根据元素值组合 XML 个节点并为某些元素创建子节点
样本输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<Order>
<OrderNumber>SO0000001</OrderNumber>
<!--All Orders with same OrderNumber are combines-->
<OrderLineNumber>000010</OrderLineNumber>
<!--Product sequence number in order-->
<OrderDate>20181026090000</OrderDate>
<CustomerNumber>0000112233</CustomerNumber>
<CustomerName>Customer name 01</CustomerName>
<Quantity>1</Quantity>
<SaleRevenue>20</SaleRevenue>
<UnitPrice>15</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ZZZ000BBB</ProductNumber>
<!--Product number in order-->
<ProductDescription>Product 01</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000001</OrderNumber>
<OrderLineNumber>000020</OrderLineNumber>
<OrderDate>20181026090000</OrderDate>
<CustomerNumber>0000112233</CustomerNumber>
<CustomerName>Customer name 01</CustomerName>
<Quantity>2</Quantity>
<SaleRevenue>20</SaleRevenue>
<UnitPrice>5</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ZZZ000AAA</ProductNumber>
<ProductDescription>Product 02</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderLineNumber>000010</OrderLineNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<Quantity>1</Quantity>
<SaleRevenue>60</SaleRevenue>
<UnitPrice>10</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00111</ProductNumber>
<ProductDescription>Product 03</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderLineNumber>000020</OrderLineNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<Quantity>2</Quantity>
<SaleRevenue>60</SaleRevenue>
<UnitPrice>20</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00222</ProductNumber>
<ProductDescription>Product 04</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderLineNumber>0000230</OrderLineNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<Quantity>3</Quantity>
<SaleRevenue>60</SaleRevenue>
<UnitPrice>30</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00333</ProductNumber>
<ProductDescription>Product 05</ProductDescription>
</Order>
</orders>
由此我喜欢使用 XSLT 1.0 或 2.0 创建以下输出
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<Order>
<OrderNumber>SO0000001</OrderNumber>
<OrderDate>20181026090000</OrderDate>
<CustomerNumber>0000112233</CustomerNumber>
<CustomerName>Customer name 01</CustomerName>
<SaleRevenue>20</SaleRevenue>
<products>
<Product>
<OrderLineNumber>000010</OrderLineNumber>
<UnitPrice>15</UnitPrice>
<Currency>USD</Currency>
<Quantity>1</Quantity>
<ProductNumber>ZZZ000BBB</ProductNumber>
<ProductDescription>Product 01</ProductDescription>
</Product>
<Product>
<OrderLineNumber>000020</OrderLineNumber>
<Quantity>2</Quantity>
<UnitPrice>5</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ZZZ000AAA</ProductNumber>
<ProductDescription>Product 02</ProductDescription>
</Product>
</products>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<products>
<Product>
<OrderLineNumber>000010</OrderLineNumber>
<Quantity>1</Quantity>
<UnitPrice>10</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00111</ProductNumber>
<ProductDescription>Product 03</ProductDescription>
</Product>
<Product>
<OrderLineNumber>000020</OrderLineNumber>
<Quantity>2</Quantity>
<UnitPrice>20</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00222</ProductNumber>
<ProductDescription>Product 04</ProductDescription>
</Product>
<Product>
<Quantity>3</Quantity>
<UnitPrice>30</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00333</ProductNumber>
<ProductDescription>Product 05</ProductDescription>
</Product>
</products>
</Order>
</orders>
我想我已经接近了,但可以让最后一块工作。
我无法将产品包含在订单中,因为我正在使用 for-each-group(我认为)。
这是我当前的 XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="orders">
<orders>
<xsl:for-each-group select="Order" group-by="OrderNumber">
<Order>
<xsl:if test="current-group()[2]">
<!--<OrderNumber name="{OrderNumber}"/>--> <!--products node-->
<xsl:copy-of select="OrderNumber"/>
<!--<xsl:copy-of select="OrderLineNumber"/>--> <!--products node-->
<xsl:copy-of select="OrderDate"/>
<xsl:copy-of select="CustomerNumber"/>
<xsl:copy-of select="CustomerName"/>
<!--<xsl:copy-of select="Quantity"/>--> <!--products node-->
<xsl:copy-of select="SaleRevenue"/>
<!--<xsl:copy-of select="UnitPrice"/>--> <!--products node-->
<xsl:copy-of select="Currency"/>
<!--<xsl:copy-of select="LineStatus"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ModelNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="SerialNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductDescription"/>--> <!--products node-->
</xsl:if>
</Order>
</xsl:for-each-group>
<xsl:if test="Order">
<products>
<xsl:for-each select="Order">
<product>
<xsl:copy-of select="OrderLineNumber"/>
<xsl:copy-of select="Quantity"/>
<xsl:copy-of select="UnitPrice"/>
<xsl:copy-of select="LineStatus"/>
<xsl:copy-of select="ProductNumber"/>
<xsl:copy-of select="ProductDescription"/>
</product>
</xsl:for-each>
</products>
</xsl:if>
</orders>
</xsl:template>
</xsl:stylesheet>
我的分组工作正常,但需要将找到的所有产品数据添加到创建的子节点产品中。
我不是 XSLT 专家,不确定我是否走在正确的道路上。
如果您希望产品嵌套在 order 元素中,您需要在创建 <order>
元素时移动相关代码块。我也看不出 current-group()[2]
上的测试试图达到什么目的,但我认为你真的不需要它。
试试这个 XSLT(其中包含复制现有节点的更短方法)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="orders">
<orders>
<xsl:for-each-group select="Order" group-by="OrderNumber">
<Order>
<xsl:copy-of select="OrderNumber,OrderDate,CustomerNumber,CustomerName,SaleRevenue"/>
<products>
<xsl:for-each select="current-group()">
<product>
<xsl:copy-of select="OrderLineNumber,UnitPrice,Currency,Quantity,ProductNumber,ProductDescription"/>
</product>
</xsl:for-each>
</products>
</Order>
</xsl:for-each-group>
</orders>
</xsl:template>
</xsl:stylesheet>
将 products
xsl:for-each
移动到 xsl:for-each-group
中,并添加到 Order
元素的绝对路径。所以将 XSLT 更改为
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="orders">
<orders>
<xsl:for-each-group select="Order" group-by="OrderNumber">
<Order>
<xsl:if test="current-group()[2]">
<!--<OrderNumber name="{OrderNumber}"/>--> <!--products node-->
<xsl:copy-of select="OrderNumber"/>
<!--<xsl:copy-of select="OrderLineNumber"/>--> <!--products node-->
<xsl:copy-of select="OrderDate"/>
<xsl:copy-of select="CustomerNumber"/>
<xsl:copy-of select="CustomerName"/>
<!--<xsl:copy-of select="Quantity"/>--> <!--products node-->
<xsl:copy-of select="SaleRevenue"/>
<!--<xsl:copy-of select="UnitPrice"/>--> <!--products node-->
<xsl:copy-of select="Currency"/>
<!--<xsl:copy-of select="LineStatus"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ModelNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="SerialNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductDescription"/>--> <!--products node-->
<!-- Moved to here -->
<products>
<xsl:for-each select="/orders/Order[OrderNumber = current()/OrderNumber]">
<product>
<xsl:copy-of select="OrderLineNumber"/>
<xsl:copy-of select="Quantity"/>
<xsl:copy-of select="UnitPrice"/>
<xsl:copy-of select="Currency"/>
<xsl:copy-of select="LineStatus"/>
<xsl:copy-of select="ProductNumber"/>
<xsl:copy-of select="ProductDescription"/>
</product>
</xsl:for-each>
</products>
</xsl:if>
</Order>
</xsl:for-each-group>
<xsl:if test="Order">
<!-- Moved for-each from here to above ^^^ -->
</xsl:if>
</orders>
</xsl:template>
</xsl:stylesheet>
这将为您提供所需的输出。
我需要根据元素值组合 XML 个节点并为某些元素创建子节点
样本输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<Order>
<OrderNumber>SO0000001</OrderNumber>
<!--All Orders with same OrderNumber are combines-->
<OrderLineNumber>000010</OrderLineNumber>
<!--Product sequence number in order-->
<OrderDate>20181026090000</OrderDate>
<CustomerNumber>0000112233</CustomerNumber>
<CustomerName>Customer name 01</CustomerName>
<Quantity>1</Quantity>
<SaleRevenue>20</SaleRevenue>
<UnitPrice>15</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ZZZ000BBB</ProductNumber>
<!--Product number in order-->
<ProductDescription>Product 01</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000001</OrderNumber>
<OrderLineNumber>000020</OrderLineNumber>
<OrderDate>20181026090000</OrderDate>
<CustomerNumber>0000112233</CustomerNumber>
<CustomerName>Customer name 01</CustomerName>
<Quantity>2</Quantity>
<SaleRevenue>20</SaleRevenue>
<UnitPrice>5</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ZZZ000AAA</ProductNumber>
<ProductDescription>Product 02</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderLineNumber>000010</OrderLineNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<Quantity>1</Quantity>
<SaleRevenue>60</SaleRevenue>
<UnitPrice>10</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00111</ProductNumber>
<ProductDescription>Product 03</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderLineNumber>000020</OrderLineNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<Quantity>2</Quantity>
<SaleRevenue>60</SaleRevenue>
<UnitPrice>20</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00222</ProductNumber>
<ProductDescription>Product 04</ProductDescription>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderLineNumber>0000230</OrderLineNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<Quantity>3</Quantity>
<SaleRevenue>60</SaleRevenue>
<UnitPrice>30</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00333</ProductNumber>
<ProductDescription>Product 05</ProductDescription>
</Order>
</orders>
由此我喜欢使用 XSLT 1.0 或 2.0 创建以下输出
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<Order>
<OrderNumber>SO0000001</OrderNumber>
<OrderDate>20181026090000</OrderDate>
<CustomerNumber>0000112233</CustomerNumber>
<CustomerName>Customer name 01</CustomerName>
<SaleRevenue>20</SaleRevenue>
<products>
<Product>
<OrderLineNumber>000010</OrderLineNumber>
<UnitPrice>15</UnitPrice>
<Currency>USD</Currency>
<Quantity>1</Quantity>
<ProductNumber>ZZZ000BBB</ProductNumber>
<ProductDescription>Product 01</ProductDescription>
</Product>
<Product>
<OrderLineNumber>000020</OrderLineNumber>
<Quantity>2</Quantity>
<UnitPrice>5</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ZZZ000AAA</ProductNumber>
<ProductDescription>Product 02</ProductDescription>
</Product>
</products>
</Order>
<Order>
<OrderNumber>SO0000999</OrderNumber>
<OrderDate>20181026090100</OrderDate>
<CustomerNumber>0000778899</CustomerNumber>
<CustomerName>Customer name 02</CustomerName>
<products>
<Product>
<OrderLineNumber>000010</OrderLineNumber>
<Quantity>1</Quantity>
<UnitPrice>10</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00111</ProductNumber>
<ProductDescription>Product 03</ProductDescription>
</Product>
<Product>
<OrderLineNumber>000020</OrderLineNumber>
<Quantity>2</Quantity>
<UnitPrice>20</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00222</ProductNumber>
<ProductDescription>Product 04</ProductDescription>
</Product>
<Product>
<Quantity>3</Quantity>
<UnitPrice>30</UnitPrice>
<Currency>USD</Currency>
<ProductNumber>ABC00333</ProductNumber>
<ProductDescription>Product 05</ProductDescription>
</Product>
</products>
</Order>
</orders>
我想我已经接近了,但可以让最后一块工作。 我无法将产品包含在订单中,因为我正在使用 for-each-group(我认为)。
这是我当前的 XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="orders">
<orders>
<xsl:for-each-group select="Order" group-by="OrderNumber">
<Order>
<xsl:if test="current-group()[2]">
<!--<OrderNumber name="{OrderNumber}"/>--> <!--products node-->
<xsl:copy-of select="OrderNumber"/>
<!--<xsl:copy-of select="OrderLineNumber"/>--> <!--products node-->
<xsl:copy-of select="OrderDate"/>
<xsl:copy-of select="CustomerNumber"/>
<xsl:copy-of select="CustomerName"/>
<!--<xsl:copy-of select="Quantity"/>--> <!--products node-->
<xsl:copy-of select="SaleRevenue"/>
<!--<xsl:copy-of select="UnitPrice"/>--> <!--products node-->
<xsl:copy-of select="Currency"/>
<!--<xsl:copy-of select="LineStatus"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ModelNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="SerialNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductDescription"/>--> <!--products node-->
</xsl:if>
</Order>
</xsl:for-each-group>
<xsl:if test="Order">
<products>
<xsl:for-each select="Order">
<product>
<xsl:copy-of select="OrderLineNumber"/>
<xsl:copy-of select="Quantity"/>
<xsl:copy-of select="UnitPrice"/>
<xsl:copy-of select="LineStatus"/>
<xsl:copy-of select="ProductNumber"/>
<xsl:copy-of select="ProductDescription"/>
</product>
</xsl:for-each>
</products>
</xsl:if>
</orders>
</xsl:template>
</xsl:stylesheet>
我的分组工作正常,但需要将找到的所有产品数据添加到创建的子节点产品中。 我不是 XSLT 专家,不确定我是否走在正确的道路上。
如果您希望产品嵌套在 order 元素中,您需要在创建 <order>
元素时移动相关代码块。我也看不出 current-group()[2]
上的测试试图达到什么目的,但我认为你真的不需要它。
试试这个 XSLT(其中包含复制现有节点的更短方法)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="orders">
<orders>
<xsl:for-each-group select="Order" group-by="OrderNumber">
<Order>
<xsl:copy-of select="OrderNumber,OrderDate,CustomerNumber,CustomerName,SaleRevenue"/>
<products>
<xsl:for-each select="current-group()">
<product>
<xsl:copy-of select="OrderLineNumber,UnitPrice,Currency,Quantity,ProductNumber,ProductDescription"/>
</product>
</xsl:for-each>
</products>
</Order>
</xsl:for-each-group>
</orders>
</xsl:template>
</xsl:stylesheet>
将 products
xsl:for-each
移动到 xsl:for-each-group
中,并添加到 Order
元素的绝对路径。所以将 XSLT 更改为
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="orders">
<orders>
<xsl:for-each-group select="Order" group-by="OrderNumber">
<Order>
<xsl:if test="current-group()[2]">
<!--<OrderNumber name="{OrderNumber}"/>--> <!--products node-->
<xsl:copy-of select="OrderNumber"/>
<!--<xsl:copy-of select="OrderLineNumber"/>--> <!--products node-->
<xsl:copy-of select="OrderDate"/>
<xsl:copy-of select="CustomerNumber"/>
<xsl:copy-of select="CustomerName"/>
<!--<xsl:copy-of select="Quantity"/>--> <!--products node-->
<xsl:copy-of select="SaleRevenue"/>
<!--<xsl:copy-of select="UnitPrice"/>--> <!--products node-->
<xsl:copy-of select="Currency"/>
<!--<xsl:copy-of select="LineStatus"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ModelNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="SerialNumber"/>--> <!--products node-->
<!--<xsl:copy-of select="ProductDescription"/>--> <!--products node-->
<!-- Moved to here -->
<products>
<xsl:for-each select="/orders/Order[OrderNumber = current()/OrderNumber]">
<product>
<xsl:copy-of select="OrderLineNumber"/>
<xsl:copy-of select="Quantity"/>
<xsl:copy-of select="UnitPrice"/>
<xsl:copy-of select="Currency"/>
<xsl:copy-of select="LineStatus"/>
<xsl:copy-of select="ProductNumber"/>
<xsl:copy-of select="ProductDescription"/>
</product>
</xsl:for-each>
</products>
</xsl:if>
</Order>
</xsl:for-each-group>
<xsl:if test="Order">
<!-- Moved for-each from here to above ^^^ -->
</xsl:if>
</orders>
</xsl:template>
</xsl:stylesheet>
这将为您提供所需的输出。