我正在尝试创建一个xslt样式表来转换xml。我研究了muenchian方法,但我不熟悉它是如何工作的。我遇到了困难,因为每个ManifestNo都可以有任意数量的SequenceNo。我试图将源xml中的平面订单分组到目标xml中具有嵌套Stop详细信息的订单。
<Orders>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<SequenceNo>1</SequenceNo>
<CustomerOrderNo>3524771-01</CustomerOrderNo>
<Weight>180</Weight>
</Order>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<SequenceNo>1</SequenceNo>
<CustomerOrderNo>3524771-02</CustomerOrderNo>
<Weight>250</Weight>
</Order>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<SequenceNo>2</SequenceNo>
<CustomerOrderNo>3524728-01</CustomerOrderNo>
<Weight>25</Weight>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<SequenceNo>1</SequenceNo>
<CustomerOrderNo>5464565-01</CustomerOrderNo>
<Weight>150</Weight>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<SequenceNo>2</SequenceNo>
<CustomerOrderNo>5874565-02</CustomerOrderNo>
<Weight>125</Weight>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<SequenceNo>2</SequenceNo>
<CustomerOrderNo>3524888-01</CustomerOrderNo>
<Weight>95</Weight>
</Order>
</Orders>
到
<Orders>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<Stop>
<SequenceNo>1</SequenceNo>
<Freight>
<CustomerOrderNo>3524771-01</CustomerOrderNo>
<Weight>180</Weight>
</Freight>
<Freight>
<CustomerOrderNo>3524771-02</CustomerOrderNo>
<Weight>250</Weight>
</Freight>
</Stop>
<Stop>
<SequenceNo>2</SequenceNo>
<Freight>
<CustomerOrderNo>3524728-01</CustomerOrderNo>
<Weight>25</Weight>
</Freight>
<Freight>
<CustomerOrderNo>3524771-02</CustomerOrderNo>
<Weight>250</Weight>
</Freight>
</Stop>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<Stop>
<SequenceNo>1</SequenceNo>
<Freight>
<CustomerOrderNo>5464565-01</CustomerOrderNo>
<Weight>150</Weight>
</Freight>
</Stop>
<Stop>
<SequenceNo>2</SequenceNo>
<Freight>
<CustomerOrderNo>5874565-02</CustomerOrderNo>
<Weight>125</Weight>
</Freight>
<Freight>
<CustomerOrderNo>3524888-0</CustomerOrderNo>
<Weight>95</Weight>
</Freight>
</Stop>
</Order>
</Orders>
答案 0 :(得分:1)
<强>予。这个XSLT 1.0转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kOrderByNum" match="Order"
use="ManifestNo"/>
<xsl:key name="kSeqInOrder" match="SequenceNo"
use="concat(../ManifestNo, '+', .)"/>
<xsl:key name="kSeqByOrderNo" match="SequenceNo"
use="../ManifestNo"/>
<xsl:template match="Order"/>
<xsl:template match="SequenceNo"/>
<xsl:template match="/*">
<Orders>
<xsl:apply-templates/>
</Orders>
</xsl:template>
<xsl:template match=
"Order
[generate-id()
=
generate-id(key('kOrderByNum', ManifestNo)[1])
]">
<Order>
<xsl:copy-of select="ManifestNo|Warehouse"/>
<xsl:apply-templates select=
"key('kSeqByOrderNo', ManifestNo)
[generate-id()
=
generate-id(key('kSeqInOrder',
concat(../ManifestNo, '+', .)
)[1]
)
]
"/>
</Order>
</xsl:template>
<xsl:template match="SequenceNo[true()]">
<Stop>
<xsl:copy-of select="."/>
<xsl:apply-templates mode="inGroup" select=
"key('kSeqInOrder',
concat(../ManifestNo, '+', .))"/>
</Stop>
</xsl:template>
<xsl:template match="SequenceNo" mode="inGroup">
<Freight>
<xsl:copy-of select="../CustomerOrderNo|../Weight"/>
</Freight>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<Orders>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<SequenceNo>1</SequenceNo>
<CustomerOrderNo>3524771-01</CustomerOrderNo>
<Weight>180</Weight>
</Order>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<SequenceNo>1</SequenceNo>
<CustomerOrderNo>3524771-02</CustomerOrderNo>
<Weight>250</Weight>
</Order>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<SequenceNo>2</SequenceNo>
<CustomerOrderNo>3524728-01</CustomerOrderNo>
<Weight>25</Weight>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<SequenceNo>1</SequenceNo>
<CustomerOrderNo>5464565-01</CustomerOrderNo>
<Weight>150</Weight>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<SequenceNo>2</SequenceNo>
<CustomerOrderNo>5874565-02</CustomerOrderNo>
<Weight>125</Weight>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<SequenceNo>2</SequenceNo>
<CustomerOrderNo>3524888-01</CustomerOrderNo>
<Weight>95</Weight>
</Order>
</Orders>
会产生想要的正确结果:
<Orders>
<Order>
<ManifestNo>283749</ManifestNo>
<Warehouse>35</Warehouse>
<Stop>
<SequenceNo>1</SequenceNo>
<Freight>
<CustomerOrderNo>3524771-01</CustomerOrderNo>
<Weight>180</Weight>
</Freight>
<Freight>
<CustomerOrderNo>3524771-02</CustomerOrderNo>
<Weight>250</Weight>
</Freight>
</Stop>
<Stop>
<SequenceNo>2</SequenceNo>
<Freight>
<CustomerOrderNo>3524728-01</CustomerOrderNo>
<Weight>25</Weight>
</Freight>
</Stop>
</Order>
<Order>
<ManifestNo>283750</ManifestNo>
<Warehouse>50</Warehouse>
<Stop>
<SequenceNo>1</SequenceNo>
<Freight>
<CustomerOrderNo>5464565-01</CustomerOrderNo>
<Weight>150</Weight>
</Freight>
</Stop>
<Stop>
<SequenceNo>2</SequenceNo>
<Freight>
<CustomerOrderNo>5874565-02</CustomerOrderNo>
<Weight>125</Weight>
</Freight>
<Freight>
<CustomerOrderNo>3524888-01</CustomerOrderNo>
<Weight>95</Weight>
</Freight>
</Stop>
</Order>
</Orders>
<强> II。 XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kSeqByOrderNo" match="SequenceNo"
use="../ManifestNo"/>
<xsl:template match="/*">
<Orders>
<xsl:for-each-group select="Order" group-by="ManifestNo">
<Order>
<xsl:copy-of select="ManifestNo|Warehouse"/>
<xsl:for-each-group select="key('kSeqByOrderNo', ManifestNo)"
group-by=".">
<xsl:copy-of select="."/>
<Stop>
<xsl:apply-templates select="current-group()"/>
</Stop>
</xsl:for-each-group>
</Order>
</xsl:for-each-group>
</Orders>
</xsl:template>
<xsl:template match="SequenceNo">
<Freight>
<xsl:copy-of select="../CustomerOrderNo|../Weight"/>
</Freight>
</xsl:template>
</xsl:stylesheet>