2011-02-04 58 views
1

我正在使用.NET4代碼觸發轉換。xslt中的文檔功能

改造工作得很好,當我寫與文檔功能的XPath直接在XSLT(見元素PanelOK的例子XSLT):

但當XPATH本身存儲在一個變量,它將無法正常工作(見元素PanelException):

<xsl:value-of select="@Customer"/> 

其中@Customer的值爲 「文件( 'myXml.xml')/ COM:根/ COM:全球/ @客」

然後我用腳本擴展我的xslt。當我沒有在xpath中使用文檔功能時,這可以正常工作,例如只/ COM:root/COM:Global/@ Customer。但是對於文檔函數,我得到異常由於未知函數,此查詢需要XsltContext。

下面是一些示例:xml1具有包含xpath表達式的值的屬性customer,xml2是可以找到值的文件,xslt是轉換xml1並評估存儲在屬性中的xpath表達式的轉換客戶應使用自定義腳本在xml2中查找值,然後在select語句中執行excation。我必須做些什麼才能做到這一點?

XML1:

<?xml version="1.0" encoding="UTF-16" standalone="no"?> 
<SFK:root xmlns:SFK="http://www.Test.com/SoftKeys"> 
    <SFK:Panel Customer="document('setting.xml')/COM:root/COM:Global/@Customer"> 
    </SFK:Panel> 
</SFK:root> 

XML2:

<?xml version="1.0" encoding="UTF-16" standalone="no"?> 
<COM:root xmlns:COM="http://www.Test.com/Comm"> 
    <COM:Global Customer="Microsoft"> 
    </COM:Global> 
</COM:root> 

XSLT:

<?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" 
       xmlns:dyn="http://exslt.org/dynamic" 
       xmlns:SFK="http://www.Test.com/SoftKeys" 
       xmlns:COM="http://www.Test.com/Comm" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       extension-element-prefixes="dyn msxsl" 
       exclude-result-prefixes="msxsl xsl SFK COM dyn"> 

    <!--Script to evaluate a string xPath to a Node. the real evaluate extension is not implemented in MS xslt processor--> 
    <msxsl:script implements-prefix="dyn" language="C#"> 
     <![CDATA[ 
      public XPathNodeIterator evaluate(XPathNavigator context, string expression) 
      { 
       XmlNamespaceManager mngr = new XmlNamespaceManager(new NameTable()); 
       mngr.AddNamespace("SFK","http://www.Test.com/SoftKeys"); 
       mngr.AddNamespace("COM","http://www.Test.com/Comm"); 
       mngr.AddNamespace("msxsl","urn:schemas-microsoft-com:xslt"); 

       return context.Select(expression,mngr); // here occurs the exception 
      } 
     ]]> 
    </msxsl:script> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="current()/SFK:root/SFK:Panel"/> 
    </xsl:template> 
    <xsl:template match="SFK:Panel"> 
     </PanelOk> 
      <xsl:value-of select="document('xml2.xml')/COM:root/COM:Global/@Customer"/> 
     </PanelOk> 
     </PanelException> 
      <xsl:value-of select="dyn:evaluate(., @Customer)"/> 
     </PanelException>  
    </xsl:template> 
</xsl:stylesheet> 
+0

好問題,+1。請參閱我的答案以解釋爲什麼在沒有擴展的情況下這是不可能的,而對於今天的.NET xslt處理器則完全不可能。解決方法是可能的,如果您表示您對此感興趣 - 可能會提出一個新問題並將其定義爲儘可能具體 - 我將很樂意提供此類解決方法。 – 2011-02-04 17:01:52

回答

1

恐怕document功能沒有在XPath規範中定義的,因此在無法使用XPath 1.0實現,如Microsoft的XPathNavigator。 document函數僅在XSLT中定義。

我不確定要建議什麼,使用Saxon 9或XQSharp,您可以使用XPath 2.0 doc函數,但我不確定您是否希望從.NET Framework的內置XSLT和XPath 1.0實現遷移到第三方XSLT和XPath 2.0實現。

1

EXSLT函數dyn:evaluate未在Microsoft XSLT處理器中實現。

如果希望的XPath表達式的不同部分用xml1的單獨元素/屬性編碼,則可以解決此問題。

當然,這是一個非常有限的解決方案,需要約定和紀律。

即使在XSLT 2.0/XPath2.0中也不支持動態評估XPath表達式。這種支持可能在更高版本中提供,但3.0版本仍具有「工作草案」狀態。