Use Muenchian grouping with a variable node-set?
I have a xsl variable who contains :
<Products>
<product>
<productId >1</productId>
<textdate>11/11/2011</textdate>
<price>200</price>
</product>
<product>
<productId >6</productId>
<textdate>11/11/2011</textdate>
<price>100</price>
</product>
<product>
<productId >1</productId>
<textdate>16/11/2011</textdate>
<price>290</price>
</product>
</Products>
I want to regroup product like this :
{ product 1 :
11/11/2011 - 200
16/11/2011 - 290 }
{ product 6
11/11/2011 - 100 }
with a simple Muenchian algorithme it's possible but I cant have a xsl:key with a match on a variable.
edit
Maybe I'm not clear,
I've this xml document mydocument.xml I try to transform :
<?xml version="1.0" encoding="utf-8" ?>
<root>
<test>somestuff</test>
</root>
My xsl must look like that :
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >开发者_StackOverflow
<xsl:output omit-xml-declaration="yes" method="xml" encoding="utf-8" />
<xsl:variable name="MyProductList" select="document('myresultlist.xml')" />
<xsl:key name="kProdById" match="$MyProductList/product" use="productId"/>
<xsl:template match=
"product[generate-id()
=
generate-id(key('kProdById',productId)[1])
]">
<xsl:value-of select="concat('
{product ', productId, ' :')"/>
<xsl:apply-templates mode="display"
select="key('kProdById',productId)"/>
}<xsl:text/>
</xsl:template>
<xsl:template match="product" mode="display">
<xsl:value-of select=
"concat('
', textdate, ' - ', price)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
When I put my variable $MyProductList in a match Visual Studio give an error, and when I'm trying to force the run my web app crash.
So I cannnot do what dimitre explain me.
Thanks for helping me
This transformation uses the Muenchian grouping method in its classic form:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kProdById" match="product" use="productId"/>
<xsl:template match=
"product[generate-id()
=
generate-id(key('kProdById',productId)[1])
]">
<xsl:value-of select="concat('
{product ', productId, ' :')"/>
<xsl:apply-templates mode="display"
select="key('kProdById',productId)"/>
}<xsl:text/>
</xsl:template>
<xsl:template match="product" mode="display">
<xsl:value-of select=
"concat('
', textdate, ' - ', price)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when applied on the provided XML document, the wanted, correct result is produced:
{product 1 :
11/11/2011 - 200
16/11/2011 - 290
}
{product 6 :
11/11/2011 - 100
}
UPDATE: The OP has shown more information and explained that the problem (in his code) is in these two lines:
<xsl:variable name="MyProductList" select="document('myresultlist.xml')" />
<xsl:key name="kProdById" match="$MyProductList/product" use="productId"/>
Solution: Just use:
<xsl:key name="kProdById" match="product" use="productId"/>
Whenever you want to reference the kProdById
key in a key()
function, make sure the wanted document is made current. In the more complicated cases this is done in XSLT 1.0 in the following way:
<!-- Temporarily switch to the document to be indexed -->
<xsl:for-each select="document('myresultlist.xml')">
<!-- Use here the key() function -->
</xsl:for-each>
<!-- Resume working with the main document here -->
Here is the same solution now applied to a document (its top-element) contained in a variable:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
>
<xsl:output method="text"/>
<my:doc>
<Products>
<product>
<productId >1</productId>
<textdate>11/11/2011</textdate>
<price>200</price>
</product>
<product>
<productId >6</productId>
<textdate>11/11/2011</textdate>
<price>100</price>
</product>
<product>
<productId >1</productId>
<textdate>16/11/2011</textdate>
<price>290</price>
</product>
</Products>
</my:doc>
<xsl:variable name="vDoc" select="document('')/*/my:doc/*"/>
<xsl:key name="kProdById" match="product" use="productId"/>
<xsl:template match="/">
<xsl:apply-templates select="$vDoc"/>
</xsl:template>
<xsl:template match=
"product[generate-id()
=
generate-id(key('kProdById',productId)[1])
]">
<xsl:value-of select="concat('
{product ', productId, ' :')"/>
<xsl:apply-templates mode="display"
select="key('kProdById',productId)"/> }
<xsl:text/>
</xsl:template>
<xsl:template match="product" mode="display">
<xsl:value-of select=
"concat('
', textdate, ' - ', price)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when this transformation is applied on any document (not used), again the wanted result is produced:
{product 1 :
11/11/2011 - 200
16/11/2011 - 290 }
{product 6 :
11/11/2011 - 100 }
精彩评论