简体   繁体   English

在C#中将Saxon的XdmNode写入流时如何包含CDATA

[英]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. 我有一个通过转换生成的XdmNode对象,我需要将其写入包含某些CDATA的流中,但是我无法获得包含CDATA转义的输出。

Is this because I'm not going through the process of serialization, eg, using the Serializer class? 这是因为我没有进行序列化的过程,例如,使用Serializer类吗? 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. 我可以看到Serializer类在Java中有一个serializeNode()方法,但在C#中却没有。。。只有transform / etc似乎能够“使用”它。 Or is this a problem around the cdata-section-elements statement? 还是cdata-section-elements语句周围的问题?

Using the XML and XSLT from here to illustrate: How do I force xslt transformation to load data into cdata sections? 从此处使用XML和XSLT进行说明: 如何强制xslt转换将数据加载到cdata节中?

This uses .NET 4.5 with Saxon 9.6.0.6 in C#. 这使用.NET 4.5和C#中的Saxon 9.6.0.6。

C# code: 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: 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: 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. 似乎您想要做的是将XdmNode发送到序列化器,以使其使用序列化器上设置的属性进行序列化。 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 "." XQuery表达式“。” 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 . 顺便说一句,Serializer的API文档没有说明CDATA_SECTION_ELEMENTS属性应采用什么形式,但我认为它可能是用Clark表示法的QNames的空格分隔的序列,即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.) (这类似于Java JAXP界面中经常运行“身份转换”的方法。但是身份查询要简单得多。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM