在 C# 中将 Saxon 的 XdmNode 写入 Stream 时如何包含 CDATA
How to include CDATA when writing Saxon's XdmNode to Stream in C#
我有一个由转换生成的 XdmNode 对象,我需要将其写入包含一些 CDATA 的流,但我无法获得包含 CDATA 转义的输出。
这是因为我没有完成序列化过程,例如,使用 Serializer class?如果是这样,我该怎么做?我可以看到 Serializer class 在 Java 中有一个 serializeNode() 方法,但在 C# 中没有...只有 transform/etc 似乎能够 "use" 它。或者这是 cdata-section-elements 语句的问题?
使用此处的 XML 和 XSLT 进行说明:
How do I force xslt transformation to load data into cdata sections?
这在 C# 中使用 .NET 4.5 和 Saxon 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>
看来您想要做的是将 XdmNode 发送到序列化程序,以使用在序列化程序上设置的属性对其进行序列化。最简单的方法可能是 运行 一个虚拟查询:
QueryCompiler qc = Processor.NewQueryCompiler();
QueryEvaluator qe = qc.Compile(".").Load();
qe.ContextItem = xdmNode;
qe.Run(serializer);
XQuery 表达式“.”只是 returns 上下文项。
顺便说一下,Serializer 的 API 文档没有说明 CDATA_SECTION_ELEMENTS 属性 应该采用什么形式,但我认为它可能是 Clark 中的一个空格分隔的 QName 序列符号,即 Q{uri}local
。或者,如果没有名称空间,则只是本地名称。
(这类似于 运行 宁 "identity transformation" 的 Java JAXP 接口中经常使用的方法。但是身份查询要简单得多。)
我有一个由转换生成的 XdmNode 对象,我需要将其写入包含一些 CDATA 的流,但我无法获得包含 CDATA 转义的输出。
这是因为我没有完成序列化过程,例如,使用 Serializer class?如果是这样,我该怎么做?我可以看到 Serializer class 在 Java 中有一个 serializeNode() 方法,但在 C# 中没有...只有 transform/etc 似乎能够 "use" 它。或者这是 cdata-section-elements 语句的问题?
使用此处的 XML 和 XSLT 进行说明: How do I force xslt transformation to load data into cdata sections?
这在 C# 中使用 .NET 4.5 和 Saxon 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>
看来您想要做的是将 XdmNode 发送到序列化程序,以使用在序列化程序上设置的属性对其进行序列化。最简单的方法可能是 运行 一个虚拟查询:
QueryCompiler qc = Processor.NewQueryCompiler();
QueryEvaluator qe = qc.Compile(".").Load();
qe.ContextItem = xdmNode;
qe.Run(serializer);
XQuery 表达式“.”只是 returns 上下文项。
顺便说一下,Serializer 的 API 文档没有说明 CDATA_SECTION_ELEMENTS 属性 应该采用什么形式,但我认为它可能是 Clark 中的一个空格分隔的 QName 序列符号,即 Q{uri}local
。或者,如果没有名称空间,则只是本地名称。
(这类似于 运行 宁 "identity transformation" 的 Java JAXP 接口中经常使用的方法。但是身份查询要简单得多。)