2013-02-14 81 views
1

我的(簡化的)輸入XML文件包含以下:XSLT解析XML字符串轉換成可變的,並且使用XPath

<?xml version="1.0" encoding="UTF-8"?> 
<main> 
    <DATA_RECORD> 
     <MESSAGE>&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;</MESSAGE> 
    </DATA_RECORD> 
</main> 

消息元素值是字符轉義XML實例。它表示以下XML:

<pd> 
    <cdhead version="13"/> 
</pd> 

我想在輸入的XML應用XSL轉換並以某種方式解析消息內容到一個變量,使用XPath表達式來訪問它的細節。
我試着添加一個javascript函數如下,但腳本返回的對象顯然是不正確的DOM子類(請參閱下面的結果)。爲了完整起見,我添加了一個額外的函數,以字符串的形式返回DOM內容。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ms="urn:schemas-microsoft-com:xslt" 
    xmlns:my="http://example.com/my" 
    exclude-result-prefixes="ms my"> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <ms:script language="JScript" implements-prefix="my"> 
     <![CDATA[ 
     function parseToDOM (input) { 
     var doc = new ActiveXObject('Msxml2.DOMDocument.6.0'); 
     doc.loadXML (input); 
     return doc.documentElement; 
     }; 
     function parseToXMLString (input) { 
     var doc = new ActiveXObject('Msxml2.DOMDocument.6.0'); 
     doc.loadXML (input); 
     return doc.documentElement.xml; 
     }; 
     ]]> 
    </ms:script> 

    <xsl:template match="/"> 
     <root> 
      <xsl:apply-templates/> 
     </root> 
    </xsl:template> 

    <xsl:template match="DATA_RECORD"> 
      <xsl:variable name="DOM"><xsl:copy-of select="my:parseToDOM (MESSAGE)"/></xsl:variable> 
      <xsl:variable name="XML"><xsl:copy-of select="my:parseToXMLString (MESSAGE)"/></xsl:variable> 

      <msg1><xsl:value-of select="$XML"/></msg1> 
      <msg2><xsl:value-of select="$XML" disable-output-escaping="yes"/></msg2> 
      <dom><xsl:copy-of select="$DOM"/></dom> 
      <version><xsl:value-of select="$DOM/pd/cdhead/@version"/></version> 
    </xsl:template> 

    <xsl:template match="text()"/> 
</xsl:stylesheet> 

結果:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <msg1>&lt;pd&gt; 
    &lt;cdhead version="13"/&gt; 
&lt;/pd&gt;</msg1> 
    <msg2><pd> 
    <cdhead version="13"/> 
</pd></msg2> 
    <dom/> 
    <version></version> 
</root> 

我怎樣才能讓JScript函數返回一個結果,它允許使用XPath?
順便問一下,是否有一些XSLT 1.0函數可用,它允許將轉義的XML字符串解析爲允許使用Xpath的結果?

加成

我一直在嘗試一些變化,並得到更接近的解決方案。首先,Altova XMLSpy允許選擇xsl處理器,並在使用內置處理器時產生上述結果。當然,我需要MSXML 6.0,當選擇那個時,出現錯誤,因爲我不得不解析input.text。但是,在JavaScript中做了額外的東西之後,我只能成功地在結果中使用Xpath表達式。發現雖然&#60;等被解析爲&lt;等,但這不足以得出正確的DOM結果。所以我採取了第一個無用的輸入字符串。
但我碰到另一個障礙:下面的工作正常,它不會當我使用input.text而不是下面的文字。

請參閱下面的xslt。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ms="urn:schemas-microsoft-com:xslt" 
    xmlns:my="http://example.com/my" 
    exclude-result-prefixes="ms my"> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <ms:script language="JScript" implements-prefix="my"> 
     <![CDATA[ 
     function parseToDOM (input) { 
      var doc = new ActiveXObject('Msxml2.DOMDocument.6.0'); 
      doc.loadXML (unescapeXML ('&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;')); 
      //doc.loadXML (unescapeXML (input.text)); 
      return doc; 
     }; 
     function unescapeXML (str) { 
      var ostr = str; 
      ostr = ostr.replace (/&#34;/g, '"'); 
      ostr = ostr.replace (/&#60;/g, '<'); 
      ostr = ostr.replace (/&#61;/g, '='); 
      ostr = ostr.replace (/&#62;/g, '>'); 
      return ostr; 
     }; 
     ]]> 
    </ms:script> 

    <xsl:template match="/"> 
     <root> 
      <xsl:apply-templates/> 
     </root> 
    </xsl:template> 

    <xsl:template match="DATA_RECORD"> 
     <xsl:variable name="msg" select="my:parseToDOM (MESSAGE)"/> 
     <tst><xsl:value-of select="$msg/pd/cdhead/@version"/></tst> 
    </xsl:template> 

</xsl:stylesheet> 

現在導致

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<tst>13</tst> 
</root> 

這就是我想要的東西。

但正如上面所說,當我的評論文字的解析和使用輸入代替,就像這樣:

//doc.loadXML (unescapeXML ('&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;')); 
doc.loadXML (unescapeXML (input.text)); 

我得到以下錯誤(在Altova的XML間諜與MSXML 6.0 XSLT解析器) :

XSL transformation failed due to following error: 

Microsoft JScript runtime error 
'undefined' is null or not an object 
line = 10, col = 3 (line is offset from the start of the script block). 
Error returned from property or method call. 

指向第一個javascript替換語句的指針。

而且也,IE9不能正確處理以下事項:

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="test.xslt"?> 
<main> 
    <DATA_RECORD> 
    <MESSAGE>&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;</MESSAGE> 
    </DATA_RECORD> 
</main> 

當我打開IE9這個文件(其中試驗。XSLT是轉型的版本,其中輸入被忽略,而不是一個文字處理,因此,一個是在XML間諜OK),我得到一個處理錯誤:

XML5001: Applying Integrated XSLT Handling. 
XSLT8690: XSLT processing failed. 

爲什麼這一切,怎麼能我糾正它?

+1

你在哪裏試圖使用它?它是在.NET代碼中,還是在IE中? – JLRishe 2013-02-14 08:54:26

+0

這是一個XML間諜轉換,用於手動執行或作爲從XML文件引用的xslt,以便可以在IE9中打開該XML文件。輸入來自Toad查詢結果保存,其中查詢的列之一包含XML字符串。 – Maestro13 2013-02-14 08:57:53

回答

2

從上面的ADDITION開始,我通過微調了一下來達成了一個解決方案。
爲了避免必須做input.text並使用普通input來代替,xsl必須包含元素轉換爲字符串,方法是應用xslt 字符串函數(我以爲它已經是字符串了,但顯然這不是案件)。另外,現在沒有必要再使用替換語句。
因此

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ms="urn:schemas-microsoft-com:xslt" 
    xmlns:my="http://example.com/my" 
    exclude-result-prefixes="ms my"> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <ms:script language="JScript" implements-prefix="my"> 
     <![CDATA[ 
     function parseToDOM (input) { 
      var doc = new ActiveXObject('Msxml2.DOMDocument.6.0'); 
      doc.loadXML (input); 
      return doc; 
     }; 
     ]]> 
    </ms:script> 

    <xsl:template match="/"> 
     <root> 
      <xsl:apply-templates/> 
     </root> 
    </xsl:template> 

    <xsl:template match="DATA_RECORD"> 
     <xsl:variable name="msg" select="my:parseToDOM (string(MESSAGE))"/> 
     <tst><xsl:value-of select="$msg/pd/cdhead/@version"/></tst> 
    </xsl:template> 

</xsl:stylesheet> 

作品:當上

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="test.xslt"?> 
<main> 
    <DATA_RECORD> 
    <MESSAGE>&#60;pd&#62;&#10; &#60;cdhead version&#61;&#34;13&#34;/&#62;&#10;&#60;/pd&#62;</MESSAGE> 
    </DATA_RECORD> 
</main> 

施加的結果是

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<tst>13</tst> 
</root> 

不幸,IE9仍然失敗與稱爲XSLT加載XML;我發現了爲什麼。
我必須在Internet選項/高級/安全/允許活動內容在我的計算機上的文件中運行 - 也重新啓動IE - 這使得IE9正確處理文件中的框。當然,不是html的結果意味着結果只能在F12/Script選項卡中查看,但這僅僅是一個例子,我將它合併到生成適當html的xslt中。