2011-05-23 39 views
1

誰能告訴我爲什麼下面的XSL在IE9中愉快地轉換下面的XML,但是在所有版本的Visual Studio下,相同的轉換都失敗了?如果我在IE 9中打開XML文件,它會被轉換並且輸出如預期的那樣,但是如果我在Visual Studio中對XML文件進行相同的轉換(使用工具欄上的「啓動XSLT」按鈕),我會得到一個JScriptException話說功能有望上線Visual Studio和IE之間行爲的XSL/JScript差異

var node = root.nextNode(); 

的修復似乎是改變javascript函數來做,而不是執行以下操作:

function test(root, attr) 
{ 
    root.MoveNext(); 
    var node = root.Current; 
    return node.Select("breakfast" + attr); 
} 

但這種失敗,則在IE中XSLT轉換!我似乎無法取勝!

XSL:

<!--<?xml version="1.0"?>--> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
xmlns:user="urn:custom-scripts"> 
<msxsl:script language="JScript" implements-prefix="user"> 
    <![CDATA[ 
function test(root, attr) 
{ 
    var node = root.nextNode(); 
    return node.selectSingleNode("breakfast" + attr); 
} 
]]> 
</msxsl:script> 
    <xsl:template match="/"> 
    <HTML> 
     <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt; 
      background-color:#EEEEEE"> 
      <xsl:value-of select="user:test(., '-menu')"/> 
     </BODY> 
    </HTML> 
    </xsl:template> 
</xsl:stylesheet> 

目標XML:

<?xml version='1.0'?> 
<?xml-stylesheet type="text/xsl" href="simple.xsl" ?> 
<breakfast-menu> 
    <food> 
    <name>Belgian Waffles</name> 
    <price>$5.95</price> 
    <description>Two of our famous Belgian Waffles 
     with plenty of real maple syrup.</description> 
    <calories>650</calories> 
    </food> 
    <food> 
    <name>Homestyle Breakfast</name> 
    <price>$6.95</price> 
    <description>Two eggs, bacon or sausage, toast, 
     and our ever-popular hash browns.</description> 
    <calories>950</calories> 
    </food> 
</breakfast-menu> 

回答

2

那麼IE使用MSXML作爲其XSLT處理器(我認爲IE 9使用MSXML 6),而Visual Studio使用XslCompiledTransform。由MSXML和XslCompiledTransform公開的和使用的API差別很大,所以不要指望針對MSXML API編寫的擴展函數代碼能夠與XslCompiledTransform和.NET API一起使用。有關在使用擴展功能時XSLT/XPath類型如何映射到.NET類型的信息,請參見http://msdn.microsoft.com/en-us/library/wxaw5z5e.aspx。在你的情況下,你從XSLT傳入一個節點集和一個字符串,映射到一個XPathNodeIterator和一個.NET中的String。 這裏是一個快速的嘗試重寫你的擴展功能,用於.NET:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
xmlns:user="urn:custom-scripts"> 
    <msxsl:script language="JScript" implements-prefix="user"> 
    <![CDATA[ 
function test(nodeIterator, string) 
{ 
    nodeIterator.MoveNext(); 
    return nodeIterator.Current.SelectSingleNode("breakfast" + string); 
} 
]]> 
    </msxsl:script> 
    <xsl:template match="/"> 
    <HTML> 
     <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt; 
      background-color:#EEEEEE"> 
     <xsl:value-of select="user:test(., '-menu')"/> 
     </BODY> 
    </HTML> 
    </xsl:template> 
</xsl:stylesheet> 

[編輯] 哎呀,我錯過了你已經找到自己的.NET代碼,只需要知道如何編寫代碼,對陣雙方XSLT處理器。這很困難。你的目標平臺和你的目標是什麼,你想爲IE編寫XSLT,但用VS開發嗎?還是你真的需要在IE和.NET平臺中使用相同的樣式表?

下面是編寫一個擴展功能兩種類型的處理器企圖:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
xmlns:user="urn:custom-scripts"> 
    <msxsl:script language="JScript" implements-prefix="user"> 
    <![CDATA[ 
function test(nodeSet, string) 
{ 
    if (typeof nodeSet.nextNode !== 'undefined') { 
    var node = nodeSet.nextNode(); 
    return node.selectSingleNode('breakfast' + string); 
    } 
    else if (typeof nodeSet.MoveNext !== 'undefined') { 
    nodeSet.MoveNext(); 
    return nodeSet.Current.SelectSingleNode("breakfast" + string); 
    } 
} 
]]> 
    </msxsl:script> 
    <xsl:template match="/"> 
    <HTML> 
     <BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt; 
      background-color:#EEEEEE"> 
     <xsl:value-of select="user:test(., '-menu')"/> 
     </BODY> 
    </HTML> 
    </xsl:template> 
</xsl:stylesheet> 
+0

謝謝 - 我想你已經找到了答案。我不打算爲兩者開發,我想這只是一個工作流程問題 - 我在部署在IE上之前在Visual Studio中進行了調試,所以這給我帶來了一些麻煩。 – 2011-05-23 11:33:42

1

你可能會發現嵌入到Visual Studio中的瀏覽器不是IE9。它最有可能是IE8的一個版本,或者IE7依賴於Visual Studio發佈時的穩定版本。

我對XLST解釋不清楚爲什麼它不起作用,但這可能會解釋您看到的行爲差異。