开发者

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('&#xA;{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('&#xA;', 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('&#xA;{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('&#xA;', 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('&#xA;{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('&#xA;', 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 }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜