是XmlTextWriter负责输出转义实体。因此,如果您执行以下操作:
using (XmlTextWriter w = new XmlTextWriter("test.xml", Encoding.UTf8))
{
w.WriteString("");
}
在 text.xml 中还会出现一个转义的 ampersand 输出 &#x10
,而这不是您想要的。您希望保留 
序列原始状态。
我提出的解决方案是创建一个新的 StreamWriter 实现,能够检测到像 "
" 这样的转义字符串:
public class NonXmlEscapingStreamWriter : StreamWriter
{
private const string AmpToken = "amp";
private int _bufferState = 0;
public NonXmlEscapingStreamWriter(string path)
: base(path)
{
}
public override void Write(char value)
{
if (value == '&')
{
if (_bufferState == 0)
{
_bufferState++;
return;
}
else
{
_bufferState = 0;
}
}
else if (value == ';')
{
if (_bufferState > 1)
{
_bufferState++;
return;
}
else
{
Write('&');
Write(AmpToken);
_bufferState = 0;
}
}
else if (value == '\n')
{
base.Write(" ");
return;
}
base.Write(value);
}
public override void Write(string value)
{
if (_bufferState > 0)
{
if (value == AmpToken)
{
_bufferState++;
return;
}
else
{
Write('&');
_bufferState = 0;
}
}
base.Write(value);
}
public override void Write(char[] buffer, int index, int count)
{
if (_bufferState > 2)
{
_bufferState = 0;
base.Write('&');
string replace;
if ((buffer != null) && ((replace = GetReplaceLength(buffer, index, count)) != null))
{
base.Write(replace);
base.Write(buffer, index + replace.Length, count - replace.Length);
return;
}
else
{
base.Write(AmpToken);
base.Write(';');
}
}
base.Write(buffer, index, count);
}
public override void Write(char[] buffer)
{
Write(buffer, 0, buffer != null ? buffer.Length : 0);
}
private string GetReplaceLength(char[] buffer, int index, int count)
{
const string token = "#10;";
if ((index + count) < token.Length)
return null;
for(int i = 0; i < token.Length; i++)
{
if (buffer[index + i] != token[i])
return null;
}
return token;
}
}
你可以像这样使用它:
using (XmlTextWriter w = new XmlTextWriter(new NonXmlEscapingStreamWriter("test.xml")))
{
element.WriteTo(w);
}
注意:尽管它能够检测到孤立的 \n 序列,但我建议您确保在原始文本中所有的 \n
都已经被转义,因此,在实际输出 XML 之前,您需要将 \n
替换为 
,就像这样:
string example = "This is a stringWith new lines in it"
XCData
代替XText
呢? - sellmeadog