2015-07-21 23 views
0

我有一個XdmNode對象生成的變換,我需要寫入包含一些CDATA的流,但無法獲得包含CDATA轉義的輸出。如何在C#中將Saxon的XdmNode寫入流時包含CDATA

這是因爲我沒有經歷序列化過程,例如使用Serializer類?如果是這樣,我該怎麼做?我可以看到Serializer類在Java中有一個serializeNode()方法,但在C#中沒有......只有變換/ etc似乎能夠「使用」它。或者這是一個圍繞cdata-section-elements聲明的問題?

從這裏使用XML和XSLT來說明: How do I force xslt transformation to load data into cdata sections?

這在C#中使用.NET 4.5與撒克遜9.6.0.6。

C#代碼:

Processor processor = new Processor(); 
XdmNode node = GetNode(processor); //gets XdmNode for XML doc below 
XsltTransformer transformer = GetTransformer(processor); //gets transform below 

transformer.InitialContextNode = node; 
XdmDestination output = new XdmDestination(); 
transformer.Run(output); 
string results = output.XdmNode.OuterXml; 

using (XmlWriter writer = XmlWriter.Create(Console.Out)) 
{ 
    output.XdmNode.WriteTo(writer); 
} 

XSLT:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes" 
    cdata-section-elements="num"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

XML:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

預期輸出:

<nums> 
    <num><![CDATA[01]]></num> 
    <num><![CDATA[02]]></num> 
    <num><![CDATA[03]]></num> 
    <num><![CDATA[04]]></num> 
    <num><![CDATA[05]]></num> 
    <num><![CDATA[06]]></num> 
    <num><![CDATA[07]]></num> 
    <num><![CDATA[08]]></num> 
    <num><![CDATA[09]]></num> 
    <num><![CDATA[10]]></num> 
</nums> 

實際輸出(控制檯上都和字符串):

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 
+0

你所需要的'XdmDestination'其他原因?或者你是否正在尋找一種方法來編寫一個CDATA部分和其他用'xsl:output'定義的選項的文件?在這種情況下,請使用http://www.saxonica.com/html/documentation/dotnetdoc/Saxon/Api/Serializer.html而不是XdmDestination。 –

+0

@Martin - 是的,我們需要轉換來創建一個XdmNode,因爲其他原因(像往常一樣,上述代碼背後的真正問題要複雜得多)。如果有幫助的話:我們有一部分代碼庫可以進行各種轉換,並且可以與XdmNodes協同工作,另一部分有時會使用其中一部分,並將XdmNode寫入流(通過HTTP)。這是後面我們遇到的問題 - 接收端(並非總是在我們的控制下)沒有看到它應該在的CDATA標記(只是XML)(上面重新創建,所以我們認爲它是流出而不是讀入) 。 – user426445

+0

那麼XdmNode所代表的XSLT/XPath/XQuery數據模型並不知道任何CDATA節,因此當您的轉換創建XdmNode時,它們不包含任何CDATA節,因爲這是串行化級別上的語法糖,並未在樹形模型中表示節點。 –

回答

1

看來你想要做的是一個XdmNode發送到串行把它系列化與被在串行設置的屬性。執行此操作的最簡單方法可能是運行虛擬查詢:

QueryCompiler qc = Processor.NewQueryCompiler(); 
QueryEvaluator qe = qc.Compile(".").Load(); 
qe.ContextItem = xdmNode; 
qe.Run(serializer); 

XQuery表達式「。」只是返回上下文項。

順便說一下,Serializer的API文檔沒有說明CDATA_SECTION_ELEMENTS屬性應該採用什麼形式,但我認爲它可能是一個用Clark表示的空格分隔的QNames序列,即Q{uri}local。如果沒有名稱空間,或者只是本地名稱。

(這類似於經常在運行的「身份轉換」的Java的JAXP接口使用的方法。但是,一個身份查詢要簡單得多。)

+0

謝謝 - 我們也在考慮身份轉換;很高興知道有一個更簡單的選擇。 – user426445

相關問題