我正在努力将平面XML转换为分层XML。我也坚持使用XSLT 1.0。它表现得像是想做我正在尝试的事情,但它并不完全存在。您可能必须运行它才能看到。显然,我需要了解这些键是如何工作的。我发现的几乎所有示例都基于属性的值......而不是不同节点之间的交叉引用。
以下是我的意见:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<tns:getDataRS xmlns:tns="http://www.myco.com/DataService">
<tns:Acknowledgement>Process completed successfully.</tns:Acknowledgement>
<tns:customer>
<tns:customerID>210</tns:customerID>
<tns:visitID>12</tns:visitID>
<tns:storeID>1</tns:storeID>
<tns:storeOrder>28</tns:storeOrder>
<tns:itemID>1</tns:itemID>
<tns:customerSalesDate>2014-09-26</tns:customerSalesDate>
</tns:customer>
<tns:customer>
<tns:customerID>210</tns:customerID>
<tns:visitID>12</tns:visitID>
<tns:storeID>1</tns:storeID>
<tns:storeOrder>28</tns:storeOrder>
<tns:itemID>3</tns:itemID>
<tns:customerSalesDate>2014-09-26</tns:customerSalesDate>
</tns:customer>
<tns:customer>
<tns:customerID>211</tns:customerID>
<tns:visitID>31</tns:visitID>
<tns:storeID>2</tns:storeID>
<tns:storeOrder>48</tns:storeOrder>
<tns:itemID>2</tns:itemID>
<tns:customerSalesDate>2014-09-26</tns:customerSalesDate>
</tns:customer>
<tns:customer>
<tns:customerID>211</tns:customerID>
<tns:visitID>31</tns:visitID>
<tns:storeID>2</tns:storeID>
<tns:storeOrder>48</tns:storeOrder>
<tns:itemID>4</tns:itemID>
<tns:customerSalesDate>2014-09-26</tns:customerSalesDate>
</tns:customer>
<tns:item>
<tns:customerID>210</tns:customerID>
<tns:visitID>12</tns:visitID>
<tns:storeID>1</tns:storeID>
<tns:itemID>1</tns:itemID>
<tns:unitPrice>2.95</tns:unitPrice>
<tns:quantity>4</tns:quantity>
</tns:item>
<tns:item>
<tns:customerID>211</tns:customerID>
<tns:visitID>31</tns:visitID>
<tns:storeID>2</tns:storeID>
<tns:itemID>2</tns:itemID>
<tns:unitPrice>3.29</tns:unitPrice>
<tns:quantity>2</tns:quantity>
</tns:item>
<tns:item>
<tns:customerID>210</tns:customerID>
<tns:visitID>12</tns:visitID>
<tns:storeID>1</tns:storeID>
<tns:itemID>3</tns:itemID>
<tns:unitPrice>4.99</tns:unitPrice>
<tns:quantity>1</tns:quantity>
</tns:item>
<tns:item>
<tns:customerID>211</tns:customerID>
<tns:visitID>31</tns:visitID>
<tns:storeID>2</tns:storeID>
<tns:itemID>4</tns:itemID>
<tns:unitPrice>6.95</tns:unitPrice>
<tns:quantity>2</tns:quantity>
</tns:item>
</tns:getDataRS>
</env:Body>
</env:Envelope>
这是我的XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tns="http://www.myco.com/DataService">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="storeKey" match="*[local-name() = 'storeID']" use="."/>
<xsl:key name="orderKey" match="*[local-name() = 'storeOrder']" use="."/>
<xsl:key name="customerKey" match="*[local-name() = 'customerID']" use="."/>
<xsl:key name="itemKey" match="*[local-name() = 'itemID']" use="."/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name() = 'getDataRS']">
<xsl:copy>
<tns:stores>
<xsl:for-each select="//*[local-name() = 'storeID'][count(. | key('storeKey', .)) > 0]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</tns:stores>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name() = 'storeID']">
<tns:store>
<xsl:copy-of select="."/>
<tns:orders>
<xsl:for-each select="../*[local-name() = 'storeOrder'][count(. | key('orderKey', .)) > 0]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</tns:orders>
</tns:store>
</xsl:template>
<xsl:template match="*[local-name() = 'storeOrder']">
<tns:order><xsl:value-of select="."/></tns:order>
<tns:salesDate><xsl:value-of select="../*[local-name() = 'customerSalesDate']"/></tns:salesDate>
<tns:customers>
<xsl:for-each select="../*[local-name() = 'customerID'][count(. | key('customerKey', .)) > 0]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</tns:customers>
</xsl:template>
<xsl:template match="*[local-name() = 'customerID']">
<tns:customer>
<xsl:copy-of select="."/>
<xsl:copy-of select="../*[local-name() = 'visitID']"/>
<tns:items>
<xsl:for-each select="../*[local-name() = 'itemID'][count(. | key('itemKey', .)) > 0]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</tns:items>
</tns:customer>
</xsl:template>
<xsl:template match="*[local-name() = 'itemID']">
<tns:item>
<xsl:copy-of select="."/>
<xsl:copy-of select="../*[local-name() = 'unitPrice']"/>
<xsl:copy-of select="../*[local-name() = 'quantity']"/>
</tns:item>
</xsl:template>
</xsl:stylesheet>
这是我想要的输出:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<tns:getDataRS xmlns:tns="http://www.myco.com/DataService">
<tns:Acknowledgement>Process completed successfully.</tns:Acknowledgement>
<tns:stores>
<tns:store>
<tns:storeID>1</tns:storeID>
<tns:orders>
<tns:order>28</tns:order>
<tns:salesDate>2014-09-26</tns:salesDate>
<tns:customers>
<tns:customer>
<tns:customerID>210</tns:customerID>
<tns:visitID>12</tns:visitID>
<tns:items>
<tns:item>
<tns:itemID>1</tns:itemID>
<tns:unitPrice>2.95</tns:unitPrice>
<tns:quantity>4</tns:quantity>
</tns:item>
<tns:item>
<tns:itemID>3</tns:itemID>
<tns:unitPrice>4.99</tns:unitPrice>
<tns:quantity>1</tns:quantity>
</tns:item>
</tns:items>
</tns:customer>
</tns:customers>
</tns:orders>
</tns:store>
<tns:store>
<tns:storeID>2</tns:storeID>
<tns:orders>
<tns:order>48</tns:order>
<tns:salesDate>2014-09-26</tns:salesDate>
<tns:customers>
<tns:customer>
<tns:customerID>211</tns:customerID>
<tns:visitID>31</tns:visitID>
<tns:items>
<tns:item>
<tns:itemID>2</tns:itemID>
<tns:unitPrice>3.29</tns:unitPrice>
<tns:quantity>2</tns:quantity>
</tns:item>
<tns:item>
<tns:itemID>4</tns:itemID>
<tns:unitPrice>6.95</tns:unitPrice>
<tns:quantity>2</tns:quantity>
</tns:item>
</tns:items>
</tns:customer>
</tns:customers>
</tns:orders>
</tns:store>
</tns:stores>
</tns:getDataRS>
</env:Body>
</env:Envelope>