2011-06-13 101 views
4

我想出來的查找表的XSLT的樣本,我不能夠得到它的工作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簡稱樣本。謝謝您的幫助 。

+0

一些XML似乎是在樣式表..'<分類>'部分。它應該在XML文檔源中嗎? – 2011-06-13 12:29:46

+0

好問題,+1。請參閱我的回答,瞭解您所遇到的一些問題以及完整解決方案。 :) – 2011-06-13 13:22:08

回答

4

XSLT樣式表包含一個錯誤 - 根據specxsl:stylesheet(又名頂級元素)的任何子元素必須是一個非空的命名空間:

「*另外,xsl:樣式表 元素可以包含來自XSLT名稱空間的不爲 的任何元素,前提是 元素的展開名稱具有 非空名稱空間URI。」

如果您使用的XSLT處理器沒有引發錯誤,那麼它不符合規範並且不能使用。查找並使用符合規範的XSLT處理器(我正在使用.NET XslCompiledTransform,Saxon 6.5.5,...等)。

還有其他錯誤。

解決方案

  1. 定義一個新的命名空間前綴(說) 「X」:

  2. 更改嵌入式<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> 
    

    0.4:

  3. ,直到你得到這個轉型執行的代碼更多的變化。在上面的代碼中注意:<xsl:for-each select="document('')">

這樣做的目的是使樣式表成爲當前文檔。 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> 
+0

感謝您的快速指南。我使用Oracle(Sun的)Transform類進行這種轉換,並沒有發生任何錯誤。我對此很天真 - 我會更深入地檢查一下。再次感謝.. – 2011-06-13 15:08:35

+0

@ user515922:不客氣。 – 2011-06-13 16:08:19

+0

遇到了一個奇怪的問題:從XSLT文件處理XSLT時,一切正常,但當我以字符串形式接收XSL並嘗試轉換時,查找不會發生。我在這裏有問題http://stackoverflow.com/questions/6356083/xslt-lookup-using-key-when-xslt-source-is-processed-from-string-in-java。以爲你可以給小費。再次感謝 ! – 2011-06-15 10:12:17