当前位置: 动力学知识库 > 问答 > 编程问答 >

xslt - How to include CDATA when writing Saxon's XdmNode to Stream in C#

问题描述:

I have an XdmNode object generated by a transform that I need to write to a stream that includes some CDATA, but I cannot get the output to include the CDATA escaping.

Is this because I'm not going through the process of serialization, eg, using the Serializer class? If so, how do I do this? I can see the Serializer class has a serializeNode() method in Java, but not in C#... only the transform/etc seem to be able to "use" it. Or is this a problem around the cdata-section-elements statement?

Using the XML and XSLT from here to illustrate:

How do I force xslt transformation to load data into cdata sections?

This uses .NET 4.5 with Saxon 9.6.0.6 in C#.

C# code:

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>

Expected output:

<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>

Actual output (both on the console and in the string):

<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>

网友答案:

It seems that what you want to do is to send an XdmNode to a Serializer to have it serialized with the properties that are set on the Serializer. The easiest way to do this is probably to run a dummy query:

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

The XQuery expression "." simply returns the context item.

Incidentally, the API documentation for Serializer doesn't say what form the CDATA_SECTION_ELEMENTS property should take, but I think it is probably a whitespace separated sequence of QNames in Clark notation, that is Q{uri}local. Or just the local name if there are no namespaces.

(This is similar to the approach often used in the Java JAXP interface of running an "identity transformation". But an identity query is much simpler.)

分享给朋友:
您可能感兴趣的文章:
随机阅读: