使用具有变量节点集的Muenchian分组?

时间:2011-02-01 17:22:51

标签: c# xml xslt

我有一个xsl变量,其中包含:

<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>

我想重新组合这样的产品:

{ product 1 :
11/11/2011 - 200
16/11/2011 - 290 }
{ product 6
11/11/2011 - 100 }

使用简单的Muenchian算法是可能的,但我不能使用xsl:key和变量匹配。

修改

也许我不清楚,

我有这个xml文档mydocument.xml我尝试转换:

<?xml version="1.0" encoding="utf-8" ?>
<root>
   <test>somestuff</test>
</root>

我的xsl必须如此:

<?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" >
  <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>

当我将变量$ MyProductList放入匹配项时,Visual Studio会出现错误,当我试图强制运行时,我的网络应用程序崩溃。

所以我不能做什么dimitre解释我。

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

此转换以经典形式使用Muenchian分组方法:

<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>

应用于提供的XML文档时,会生成所需的正确结果

{product 1 :
11/11/2011 - 200
16/11/2011 - 290
}
{product 6 :
11/11/2011 - 100
}

更新:OP已经显示了更多信息并解释了问题(在他的代码中)是这两行:

<xsl:variable name="MyProductList" select="document('myresultlist.xml')" />
<xsl:key name="kProdById" match="$MyProductList/product" use="productId"/>

解决方案:只需使用:

<xsl:key name="kProdById" match="product" use="productId"/>

每当您想在kProdById函数中引用key()键时,请确保所需文档是最新的。在更复杂的情况下,这是通过以下方式在XSLT 1.0中完成的:

<!-- 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 -->

以下是现在应用于变量中包含的文档(其顶部元素)的相同解决方案:

<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>

当此转换应用于任何文档(未使用)时,会再次生成所需结果:

{product 1 :
11/11/2011 - 200
16/11/2011 - 290 }

{product 6 :
11/11/2011 - 100 }