В этом преобразовании используется метод группирования Мюнхена в его классической форме:
<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>
при применении к предоставленному документу XML, требуемый, правильный результат получается :
{product 1 :
11/11/2011 - 200
16/11/2011 - 290
}
{product 6 :
11/11/2011 - 100
}
ОБНОВЛЕНИЕ : ОП показал больше информации и объяснил, что проблема (в его коде) заключается в следующих двух строках:
<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('
{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>
когда это преобразование применяется к любому документу (не используется), снова получается желаемый результат:
{product 1 :
11/11/2011 - 200
16/11/2011 - 290 }
{product 6 :
11/11/2011 - 100 }