我正在试用XSLT中的查找表示例,但无法使其在中工作
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" />
<xsl:key name="classification-lookup" match="classification" use="id" />
<xsl:variable name="classification-top" select="document('')/*/classifications" />
<xsl:template match="BusinessListing">
<listing>
<id>
<xsl:value-of select="id" />
</id>
<xsl:apply-templates select="$classification-top">
<xsl:with-param name="curr-label" select="." />
</xsl:apply-templates>
</listing>
</xsl:template>
<xsl:template match="classifications">
<xsl:param name="curr-label" />
<category>
<xsl:value-of select="key('classification-lookup', $curr-label/listingData/classifications/classificationId)/description" />
</category>
</xsl:template>
<classifications>
<classification>
<id>7981</id>
<description>Category1</description>
</classification>
<classification>
<id>7982</id>
<description>Category2</description>
</classification>
<classification>
<id>7983</id>
<description>Category3</description>
</classification>
<classification>
<id>7984</id>
<description>Category4</description>
</classification>
</classifications>
</xsl:stylesheet>
来源如下。
<?xml version="1.0"?>
<BusinessListings>
<BusinessListing>
<id>1593469</id>
<listingData>
<classifications>
<classificationId>7982</classificationId>
<classificationId>7983</classificationId>
</classifications>
</listingData>
</BusinessListing>
</BusinessListings>
在下面的结果中,类别为空,但我需要来源的ClassificationId与分类标签中的Id和生成的类别相匹配。
<?xml version="1.0" encoding="UTF-8"?>
<listing>
<id>1593469</id> -- Empty I need the Category2 and Category3 here
<category/>
</listing>
我知道我可能偏离了目标,但我刚开始使用XSLT,并在这里引用了示例http://www.ibm.com/developerworks/xml/library/x-xsltip.html。谢谢你的帮助。
您的XSLT样式表包含错误——根据规范,xsl:stylesheet
的任何子元素(也称为顶级元素)都必须位于非空名称空间中:
"*此外,xsl:stylesheet元素可以包含任何不来自XSLT命名空间,前提是元素的展开名称具有非空命名空间URI。"
如果您正在使用的XSLT处理器没有引发错误,那么它是不兼容的并且有缺陷的,不应该使用。查找并使用兼容的XSLT处理器(我使用的是.NET XslCompiledTransform、Saxon 6.5.5、…等)。
还有其他错误。
解决方案:
-
定义一个前缀为"x:"的新命名空间:
-
将嵌入的
<classifications>
更改为<x:classifications>
——现在这符合规范 -
对代码执行更多的更改,直到您获得此转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="my:x" exclude-result-prefixes="x"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="classification-lookup" match="classification" use="id" /> <xsl:template match="BusinessListing"> <listing> <id> <xsl:value-of select="id" /> </id> <xsl:apply-templates/> </listing> </xsl:template> <xsl:template match="classificationId"> <xsl:variable name="vCur" select="."/> <xsl:for-each select="document('')"> <category> <xsl:value-of select= "key('classification-lookup',$vCur)/description" /> </category> </xsl:for-each> </xsl:template> <xsl:template match="text()"/> <x:classifications> <classification> <id>7981</id> <description>Category1</description> </classification> <classification> <id>7982</id> <description>Category2</description> </classification> <classification> <id>7983</id> <description>Category3</description> </classification> <classification> <id>7984</id> <description>Category4</description> </classification> </x:classifications> </xsl:stylesheet>
4.在上面的代码中,注意行:
<xsl:for-each select="document('')">
。
这样做的目的是使样式表成为当前文档。key()
函数仅对当前文档进行操作,如果希望对嵌入的classification
元素进行索引和使用,则必须更改当前文档(通常是这样)。在XSLT2.0中,key()
函数允许使用第三个参数,该参数是应该使用其索引的文档中的一个节点。
将此转换应用于提供的XML文档时:
<BusinessListings>
<BusinessListing>
<id>1593469</id>
<listingData>
<classifications>
<classificationId>7982</classificationId>
<classificationId>7983</classificationId>
</classifications>
</listingData>
</BusinessListing>
</BusinessListings>
生成所需的正确结果:
<listing>
<id>1593469</id>
<category>Category2</category>
<category>Category3</category>
</listing>