我正在尝试创建一个xslt样式表来转换xml。我曾研究过muenchian方法,但对它的工作原理并不熟悉。我遇到了一些困难,因为每个ManifestNo都可以有任意数量的SequenceNo,我正在尝试将源xml中的平面订单分组为目标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>
<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>发布于 2012-05-12 11:05:36
I.这个XSLT1.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. XSLT2.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>https://stackoverflow.com/questions/10558164
复制相似问题