【发布时间】:2015-07-21 08:47:19
【问题描述】:
我有一个由转换生成的 XdmNode 对象,我需要将其写入包含一些 CDATA 的流,但我无法获得包含 CDATA 转义的输出。
这是因为我没有经历序列化过程,例如,使用 Serializer 类吗?如果是这样,我该怎么做?我可以看到 Serializer 类在 Java 中有一个 serializeNode() 方法,但在 C# 中没有……只有转换/等似乎能够“使用”它。或者这是 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>
【问题讨论】:
-
您是否因为其他原因需要
XdmDestination?或者您是否正在寻找一种方法来编写包含 CDATA 部分和其他由xsl:output定义的选项的文件?在这种情况下,请使用 saxonica.com/html/documentation/dotnetdoc/Saxon/Api/… 而不是 XdmDestination。 -
@Martin - 是的,由于其他原因,我们需要转换来创建 XdmNode(与往常一样,上面代码背后的真正问题要复杂得多)。如果有帮助:我们的代码库的一部分进行各种转换并与 XdmNodes 一起使用,另一部分有时会采用其中的一些并将 XdmNodes 写入流(通过 HTTP)。这是我们遇到问题的后一个领域 - 接收端(并不总是在我们的控制范围内)没有看到它应该在的 CDATA 标记(只是 XML)(在上面重新创建,所以我们认为它是流输出而不是读入) .
-
XdmNode 表示的 XSLT/XPath/XQuery 数据模型不知道任何 CDATA 部分,因此当您的转换创建 XdmNodes 时,它们不包含任何 CDATA 部分,因为这是序列化级别上的语法糖,即未在节点的树模型中表示。
-
啊。那就是我出错的地方-谢谢。 net.sf.saxon.s9api 中有第二个序列化程序类(我上面提到的那个在 Saxon.Api 命名空间中),它似乎支持设置输出属性(例如,cdata-section-elements),写入流,并且有 serializeNode(XdmNode node) 方法 - 这是正确的路径吗?如果是这样,是否有人对将.NET 流与该序列化程序接受的(可能)IKVM 的 java.io.Stream 类一起使用有任何提示? (这应该是一个单独的 SO 问题吗?)
-
抱歉,我认为您必须等到 Michael Kay 或 Saxonica 的其他人出现才能回答这个问题。
标签: c# xslt transform cdata saxon