2010-05-04 45 views
2

我觸發使用.NET代碼的改造,使用文件()在XSLT 1.0功能

除非我加上「EnableDocumentFunction」屬性設置爲XSL-設置,該程序引發錯誤說..「Usage of Document() function is prohibited」 ,

其實該程序是不可編輯的,一種只讀..是否有可能編輯本身的XSL代碼,以便我可以使用document()函數?

樣本XSL和個XML是在這裏:
示例XML:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:variable name="State_Code_Trn"> 
    <State In="California" Out="CA"/> 
    <State In="CA" Out="CA"/> 
    <State In="Texas" Out="TX"/> 
    <State In="TX" Out="TX"/> 
    </xsl:variable> 

    <xsl:template name="testing" match="test_node"> 
    <xsl:variable name="test_val"> 
     <xsl:value-of select="."/> 
    </xsl:variable> 
    <xsl:element name="{name()}"> 
     <xsl:choose> 
     <xsl:when test="document('')/*/xsl:variable[@name='State_Code_Trn'] 
       /State[@In=$test_val]"> 
    <xsl:value-of select="document('')/*/xsl:variable[@name='State_Code_Trn'] 
       /State[@In=$test_val]/@Out"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>Other</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 



和樣本XML:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <test_node>California</test_node> 
    <test_node>CA</test_node> 
    <test_node> CA</test_node> 
    <test_node>Texas</test_node> 
    <test_node>TX</test_node> 
    <test_node>CAA</test_node> 
    <test_node></test_node> 
</root> 

回答

2

文檔()這裏的功能是用於訪問XSLT文檔本身,並提取xsl:變量的內容。在這種情況下,根本沒有必要使用document()函數。

因爲您在這裏使用Microsoft.Net,您應該能夠訪問XSLT的msxml擴展函數。事實上,MSXML相關的命名空間的XSLT文件

xmlns:msxsl="urn:schemas-microsoft-com:xslt" 

中已經定義這意味着您將能夠利用節點集功能輕鬆地直接訪問State_Code_Tran變量中的節點。要做到這一點,嘗試改變現有的的xsl:選擇功能如下:

<xsl:choose> 
    <xsl:when test="msxsl:node-set($State_Code_Trn)/State[@In=$test_val]"> 
    <xsl:value-of select="msxsl:node-set($State_Code_Trn)/State[@In=$test_val]/@Out"/> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:text>Other</xsl:text> 
    </xsl:otherwise> 
    </xsl:choose> 

這應該產生以下輸出

<root> 
<test_node>CA</test_node> 
<test_node>CA</test_node> 
<test_node>Other</test_node> 
<test_node>TX</test_node> 
<test_node>TX</test_node> 
<test_node>Other</test_node> 
<test_node>Other</test_node> 
</root> 

(請注意,您的一個前有一個空格「 CA是你原來的XML,這就是爲什麼它會以'Other'出現的原因,你可能需要添加一些修剪功能來應對這種情況

+0

帽子@Tim,謝謝你百萬:) :)))) – 2010-05-04 12:26:34

2

除了@ Tim-C的回答,你可以使用ext:node-set()擴展函數,其中「ext」前綴與EXSLT名稱空間相關聯:"http://exslt.org/common"

這是由XslCompiledTransform支持,並將使您的XSLT代碼更便攜一點,因爲EXSLT是一個擴展功能的標準庫。

+1

很酷。我不知道XslCompiledTransform支持。現在,如果只有它也支持XSLT2.0,那麼我會是一個快樂的人... – 2010-05-04 15:11:06

+0

感謝您的寶貴回答:) – 2010-05-06 06:01:58