Xslt for-each and key match
I have two xml data sources like this:
<orders>
<order>
<ordernumber>123</ordernumber>
<subtotal>20</subtotal>
<total>23.5</total>
</order>
<order>
<ordernumber>234</or开发者_JS百科dernumber>
<subtotal>19</subtotal>
<total>26.5</total>
</order>
</orders>
<orderitems>
<item>
<ordernumber>123</ordernumber>
<productname>test1</productname>
<sku>s9sdidk</sku>
<item>
<item>
<ordernumber>123</ordernumber>
<productname>test2</productname>
<sku>123232</sku>
<item>
<item>
<ordernumber>234</ordernumber>
<productname>test3</productname>
<sku>s9sd2d32k</sku>
<item>
<item>
<ordernumber>234</ordernumber>
<productname>test4</productname>
<sku>s9swe23</sku>
<item>
</orderitems>
and then I need to use xslt to group items by order number and get an output like this:
productname sku
test1 s9sdidk
test2 123232
---------------------------------
subtotal: 20
total: 23.5
productname sku
test3 s9sd2d32k
test4 s9swe23
---------------------------------
subtotal: 19
total: 26.5
I need to use html tags so I can't use for-each-group thing...please help! thanks in advance.
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kItemByOrdernumber" match="item" use="ordernumber"/>
<xsl:variable name="vSource2" select="document('source2.xml')"/>
<xsl:template match="text()"/>
<xsl:template match="order/ordernumber">
<xsl:variable name="vCurrent" select="."/>
<xsl:text>productname		sku
</xsl:text>
<xsl:for-each select="$vSource2">
<xsl:apply-templates
select="key('kItemByOrdernumber',$vCurrent)"/>
</xsl:for-each>
<xsl:value-of
select="concat('---------------------------------','
',
'	subtotal: ',../subtotal,'
',
'	total: ',../total,'

')"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="concat(productname,'			',
sku,'
')"/>
</xsl:template>
</xsl:stylesheet>
With first document as input and second document as source2.xml
external input, output:
productname sku
test1 s9sdidk
test2 123232
---------------------------------
subtotal: 20
total: 23.5
productname sku
test3 s9sd2d32k
test4 s9swe23
---------------------------------
subtotal: 19
total: 26.5
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kitemByOrder" match="item" use="ordernumber"/>
<xsl:param name="pmaxSize" select="100"/>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="order">
productname<xsl:text>	</xsl:text>sku
<xsl:apply-templates select="key('kitemByOrder', ordernumber)"/>
---------------------------------
subtotal: <xsl:value-of select="subtotal"/>
total: <xsl:value-of select="total"/>
<xsl:text>

</xsl:text>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="concat(productname, '		', sku, '
')"/>
</xsl:template>
<xsl:template match="orderitems"/>
</xsl:stylesheet>
when applied on the provided XML document (corrected as it was severely non-well-formed):
<t>
<orders>
<order>
<ordernumber>123</ordernumber>
<subtotal>20</subtotal>
<total>23.5</total>
</order>
<order>
<ordernumber>234</ordernumber>
<subtotal>19</subtotal>
<total>26.5</total>
</order>
</orders>
<orderitems>
<item>
<ordernumber>123</ordernumber>
<productname>test1</productname>
<sku>s9sdidk</sku>
</item>
<item>
<ordernumber>123</ordernumber>
<productname>test2</productname>
<sku>123232</sku>
</item>
<item>
<ordernumber>234</ordernumber>
<productname>test3</productname>
<sku>s9sd2d32k</sku>
</item>
<item>
<ordernumber>234</ordernumber>
<productname>test4</productname>
<sku>s9swe23</sku>
</item>
</orderitems>
</t>
produces the wanted, correct result:
productname sku
test1 s9sdidk
test2 123232
---------------------------------
subtotal: 20
total: 23.5
productname sku
test3 s9sd2d32k
test4 s9swe23
---------------------------------
subtotal: 19
total: 26.5
Note: You may use two different XML documents for the two data sources, but the processing is essentially the same, with the exception that you need to address one of them using the document()
function.
精彩评论