2012-08-10 51 views
2

我有下面的XML:兩相XSLT轉換將字符串轉換到XML第一

<?xml version="1.0" encoding="utf-8"?> 
<string> 
&lt;Table&gt; 
&lt;Rows&gt; 
&lt;Row Id="0"&gt; 
&lt;Column Name="INS_NAME" XPath="Ins.Name"&gt;Jane&lt;/Column&gt; 
&lt;Column Name="INS_LASTNAME" XPath="Ins.LastName"&gt;Smith&lt;/Column&gt; 
&lt;/Row&gt; 
&lt;Row Id="1"&gt; 
&lt;Column Name="INS_NAME" XPath="Ins.Name"&gt;Joe&lt;/Column&gt; 
&lt;Column Name="INS_LASTNAME" XPath="Ins.LastName"&gt;Miller&lt;/Column&gt; 
&lt;/Row&gt; 
&lt;Row Id="2"&gt; 
&lt;Column Name="INS_NAME" XPath="Ins.Name"&gt;George&lt;/Column&gt; 
&lt;Column Name="INS_LASTNAME" XPath="Ins.LastName"&gt;Ramsey&lt;/Column&gt; 
&lt;/Row&gt; 
&lt;/Rows&gt; 
&lt;/Table&gt; 
</string> 

,我想用 XSLT把它轉換到這個XML:

<?xml version="1.0" encoding="utf-8"?> 
<Customers> 
    <Customer><Name>Jane</Name><LastName>Smith</LastName></Customer> 
    <Customer><Name>Joe</Name><LastName>Miller</LastName></Customer> 
    <Customer><Name>George</Name><LastName>Ramsey</LastName></Customer> 
</Customers> 

我可以用兩種不同的XSLT來完成:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
    <xsl:value-of select="/" disable-output-escaping="yes" /> 
    </xsl:template> 
</xsl:stylesheet> 

然後:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
    <Customers> 
     <xsl:for-each select="Table/Rows/Row"> 
     <Customer> 
     <Name><xsl:value-of select="Column[@Name='INS_NAME']" /></Name> 
     <LastName><xsl:value-of select="Column[@Name='INS_LASTNAME']" /></LastName> 
     </Customer> 
     </xsl:for-each> 
    </Customers> 
    </xsl:template> 
</xsl:stylesheet> 

我一直在閱讀關於多相變換,但我似乎無法得到它。我已經嘗試在變量中保存第一個XSLT,但在保存到變量時似乎disable-output-escaping="yes"不起作用。

任何人都可以幫忙嗎?

謝謝。

新的信息(編輯)

我現在翻譯的字符串是這樣的:

<xsl:output method="text"/> 
    <xsl:template match="/"> 
    <xsl:variable name="stringXml"> 
     &lt;?xml version="1.0" encoding="utf-8"?&gt; 
     <xsl:value-of select="translate(translate(/,'&gt;','&gt;'),'&lt;','&lt;')" /> 
    </xsl:variable> 
... 

我該怎麼辦存儲在stringXML生成的XML轉換?

最終解決方案(編輯)

<msxml:script implements-prefix="myLib" language="C#"> 
<msxml:assembly name="System.Web"/> 
<msxml:using namespace="System.Web"/> 
<![CDATA[ 
public System.Xml.XPath.XPathNodeIterator convertText(string text) 
{ 
XmlDocument doc = new XmlDocument(); 
     doc.PreserveWhitespace = true; 
     doc.LoadXml(text); 
     return doc.CreateNavigator().Select("/"); 
} 
]]> 
</msxml:script> 

回答

2

似乎禁用輸出轉義= 「是」 不保存到 變量時工作。

你的觀察是正確的。

DOE隻影響轉化(最終)結果的序列化,不適用於中間樹

這裏是什麼W3C XSLT 1.0 specification明確地說:

XSLT處理器只能禁用輸出轉義,如果它 控制結果樹如何輸出,這可能並不總是。 case。例如,結果樹可能被用作另一個XSLT轉換的源樹,而不是被輸出。「

相同的否定的回答保持用於嘗試使用一個變量,它的值是一個字符串,包含XML文檔的文本表示。

+0

感謝您的確認。你能想到另一種將字符串轉換爲XML的方式嗎? – supercoco 2012-08-10 12:36:25

+0

不在純粹的XSLT(1.0或2.0)中。這可以使用微小的擴展功能來完成。如果你需要這個,我可以在C#中給你一個。 – 2012-08-10 12:43:03

+0

我沒有學習過擴展函數,所以我不知道我是否可以使用它。我現在用XSLT創建一個文本輸出,但我需要將存儲在變量中的結果XML轉換。這可能嗎? (請參閱原始帖子上的編輯) – supercoco 2012-08-10 13:15:08

1

我有一個類似的情況,我需要解析我的實際XML內的轉義XML。我會發布我的解決方案,以幫助別人。另請注意,我也在使用Saxon-PE解析器。

在我的情況下,我有原始的XML在子節點中包含一個轉義的XML。我需要獲取轉義XML的RootNode中的內部XML。

源XML:

<?xml version="1.0" encoding="utf-8"?> 
<MyTestXml> 
    <SomeXmlStuff> 
     <Text1>Hello</Text1> 
     <Text2>World</Text2> 
    </SomeXmlStuff> 
    <SomeEscapedXml>&lt;RootNode&gt;&lt;FirstNode&gt;Hello&lt;/FirstNode&gt;&lt;SecondNode&gt;World&lt;/SecondNode&gt;&lt;ThirdNode&gt;Again&lt;/ThirdNode&gt;&lt;/RootNode&gt;</SomeEscapedXml> 
</MyTestXml> 

當你轉義的XML,它看起來像這樣:

<RootNode> 
    <FirstNode>Hello</FirstNode> 
    <SecondNode>World</SecondNode> 
    <ThirdNode>Again</ThirdNode> 
</RootNode> 

用下面的XSLT轉換應用於XML源:

<?xml version='1.0' encoding='utf-8' ?> 
<xsl:stylesheet version="3.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:saxon="http://saxon.sf.net/" 

       exclude-result-prefixes="xsl saxon"> 

    <xsl:template match="/"> 
     <MyOutput>  
      <xsl:call-template name="GetRootNodeInnerXml"> 
       <xsl:with-param name="escapedXml" select="MyTestXml/SomeEscapedXml" /> 
      </xsl:call-template> 
     </MyOutput> 
    </xsl:template> 

    <xsl:template name="GetRootNodeInnerXml"> 
     <xsl:param name="escapedXml" required="yes" /> 

     <xsl:copy-of select="saxon:parse($escapedXml)/RootNode/node()"/> 

     <!-- You can also use this line below if you're not using saxon parser. Just make sure your parser supports XSL 3.0 --> 
     <!-- 
     <xsl:copy-of select="fn:parse-xml($escapedXml)/RootNode/node()" xmlns:fn="http://www.w3.org/2005/xpath-functions"/> 
     --> 
    </xsl:template> 
</xsl:stylesheet> 

這給你以下輸出:

<?xml version='1.0' ?> 
<MyOutput> 
    <FirstNode>Hello</FirstNode> 
    <SecondNode>World</SecondNode> 
    <ThirdNode>Again</ThirdNode> 
</MyOutput>