XSLT key()查找

时间:2011-06-13 12:19:05

标签: xslt xslt-1.0

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

在下面的结果中,类别为空,但我需要从源中分类ID与分类标记中的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。谢谢你的帮助。

1 个答案:

答案 0 :(得分:4)

您的XSLT样式表包含错误 - 根据 spec xsl:stylesheet的所有子元素(又名 top- level元素)必须位于非null命名空间中:

  

“*另外,xsl:stylesheet   元素可以包含任何元素   从XSLT名称空间,提供   元素的扩展名有一个   非空名称空间URI。 “

如果您使用的XSLT处理器没有引发错误,那么它是不合规的并且有错误,不应该使用。查找并使用兼容的XSLT处理器(我使用的是.NET XslCompiledTransform,Saxon 6.5.5,...等)。

还有其他错误。

<强>解决方案

  1. 使用前缀(例如)“x:”:

    定义新的命名空间

  2. 将嵌入式<classifications>更改为<x:classifications> - 现在符合规范。

  3. 对代码执行更多更改,直到您完成此转换:

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

    0.4。在上面的代码中,请注意以下行:<xsl:for-each select="document('')">

  4. 这样做的目的是使样式表成为当前文档。 key()函数仅对当前文档起作用,如果希望对嵌入的classification元素进行索引和使用,则必须更改当前文档(通常以这种方式)。在XSLT 2.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>