XslCompiledTransform 去除 CDATA 中的新行字符而不替换它们
XslCompiledTransform strips new line characters inside CDATA without replacing them
我有此数据的来源 xml:
<add>
<doc>
<field name="Body"><![CDATA[Line break 1\r\n\r\nline break 2\r\n\r\nline break 3\r\n\r\n Some more text.]]>
</field>
</add>
我正在使用 XslCompiledTransform 通过此 xslt 对其进行转换:
<xsl:template match="add">
<add>
<xsl:for-each select="doc">
<doc>
<xsl:apply-templates select="@* | node()" />
</doc>
</xsl:for-each>
</add>
</xsl:template>
因此 Body 字段应该直接通过而不会发生变化。执行转换的C#代码如下:
XmlDocument source = new XmlDocument();
StringReader reader = new StringReader("My source xml comes in here");
source.Load(reader);
XslCompiledTransform transformer = new XslCompiledTransform(false);
transformer.Load("xslt Path");
XmlWriterSettings settings = transformer.OutputSettings.Clone();
settings.NewLineHandling = NewLineHandling.Replace;
settings.NewLineChars = "\r\n";
StringBuilder builder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(builder, settings))
{
transformer.Transform(source, this.xsltArgs, writer);
}
string transformedXml = builder.ToString();
这个转换的结果是:
<?xml version="1.0" encoding="utf-16"?>
<add>
<doc>
<field name="Body">Line break 1 line break 2 line break 3 Some more text.</field>
</doc>
</add>
如您所见,CDATA 和换行符都已删除。可以在这个阶段删除 CDATA,但我需要保留换行符。无论我使用 NewLineHandling
和 NewLineChars
设置的哪种组合(或者,事实上,如果我完全省略它们),我都会得到相同的结果。
我还需要做些什么吗?
这已通过更改 xslt 文件解决,因此:
<xsl:template match="add">
<add>
<xsl:for-each select="doc">
<doc>
<xsl:copy-of select="field[@name = 'Body']" />
<xsl:apply-templates select="@* | node()" />
</doc>
</xsl:for-each>
</add>
</xsl:template>
<xsl:template match="field[@name = 'Body']" />
<xsl:template match="field[@name = 'Source']">
<field>
<xsl:attribute name="name">Source</xsl:attribute>
<xsl:value-of select="normalize-space(.)"/>
</field>
</xsl:template>
<xsl:template match="field[@name = 'Section']">
<field>
<xsl:attribute name="name">Section</xsl:attribute>
BikesForSale
</field>
</xsl:template>
<xsl:template match="field[@name = 'FirstSeen']">
<field>
<xsl:attribute name="name">PublishedDate</xsl:attribute>
<xsl:value-of select="."/>
</field>
</xsl:template>
...more here, removed for brevity.
添加这个:
source.PreserveWhitespace = true;
在创建文档之后,加载它之前。
或者用
补充你的XML
<field name="Body" xml:space="preserve"><![CDATA[etc..
我有此数据的来源 xml:
<add>
<doc>
<field name="Body"><![CDATA[Line break 1\r\n\r\nline break 2\r\n\r\nline break 3\r\n\r\n Some more text.]]>
</field>
</add>
我正在使用 XslCompiledTransform 通过此 xslt 对其进行转换:
<xsl:template match="add">
<add>
<xsl:for-each select="doc">
<doc>
<xsl:apply-templates select="@* | node()" />
</doc>
</xsl:for-each>
</add>
</xsl:template>
因此 Body 字段应该直接通过而不会发生变化。执行转换的C#代码如下:
XmlDocument source = new XmlDocument();
StringReader reader = new StringReader("My source xml comes in here");
source.Load(reader);
XslCompiledTransform transformer = new XslCompiledTransform(false);
transformer.Load("xslt Path");
XmlWriterSettings settings = transformer.OutputSettings.Clone();
settings.NewLineHandling = NewLineHandling.Replace;
settings.NewLineChars = "\r\n";
StringBuilder builder = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(builder, settings))
{
transformer.Transform(source, this.xsltArgs, writer);
}
string transformedXml = builder.ToString();
这个转换的结果是:
<?xml version="1.0" encoding="utf-16"?>
<add>
<doc>
<field name="Body">Line break 1 line break 2 line break 3 Some more text.</field>
</doc>
</add>
如您所见,CDATA 和换行符都已删除。可以在这个阶段删除 CDATA,但我需要保留换行符。无论我使用 NewLineHandling
和 NewLineChars
设置的哪种组合(或者,事实上,如果我完全省略它们),我都会得到相同的结果。
我还需要做些什么吗?
这已通过更改 xslt 文件解决,因此:
<xsl:template match="add">
<add>
<xsl:for-each select="doc">
<doc>
<xsl:copy-of select="field[@name = 'Body']" />
<xsl:apply-templates select="@* | node()" />
</doc>
</xsl:for-each>
</add>
</xsl:template>
<xsl:template match="field[@name = 'Body']" />
<xsl:template match="field[@name = 'Source']">
<field>
<xsl:attribute name="name">Source</xsl:attribute>
<xsl:value-of select="normalize-space(.)"/>
</field>
</xsl:template>
<xsl:template match="field[@name = 'Section']">
<field>
<xsl:attribute name="name">Section</xsl:attribute>
BikesForSale
</field>
</xsl:template>
<xsl:template match="field[@name = 'FirstSeen']">
<field>
<xsl:attribute name="name">PublishedDate</xsl:attribute>
<xsl:value-of select="."/>
</field>
</xsl:template>
...more here, removed for brevity.
添加这个:
source.PreserveWhitespace = true;
在创建文档之后,加载它之前。
或者用
补充你的XML<field name="Body" xml:space="preserve"><![CDATA[etc..