我有一个XML文档,我想加载操作然后保存回磁盘。其中一个元素的文本中包含一个不间断的空格 
。当我将文档序列化后,它作为一个不间断的空间出现,但不像原来那样代码点。此问题还会影响其他代码点,例如&
和"
,但不会影响<
和>
,因为后者在元素中不合法。您甚至不需要操纵文档来使其替换字符。
有没有办法让它作为代码点序列化? 文件示例
<Node>
<InnerNode>Some Text</InnerNode>
</Node>
代码示例
XmlDocument doc = new XmlDocument {PreserveWhitespace = true};
doc.Load(fileStream.BaseStream);
doc.Save(path);
答案 0 :(得分:1)
您的目标可以通过使用decorated XmlWriter
对象来实现。下面的代码用 
方法中的XML实体WriteString
替换了不间断的空格。
using System;
using System.Linq;
using System.Xml;
using System.IO;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
StreamReader fileStream = new StreamReader("input.xml");
string path = "output.xml";
XmlDocument doc = new XmlDocument { PreserveWhitespace = true };
doc.Load(fileStream.BaseStream);
// Do some processing...
MyXmlWriter writer = new MyXmlWriter(XmlWriter.Create(path));
doc.Save(writer);
}
}
public class MyXmlWriter : XmlWriter
{
private readonly XmlWriter writer;
public MyXmlWriter(XmlWriter writer)
{
if (writer == null) throw new ArgumentNullException("writer");
this.writer = writer;
}
// Output non-breaking space as character entity
public override void WriteString(string text)
{
string[] parts = text.Split((char)160);
for (int i = 0; i < parts.Count(); i++)
{
this.writer.WriteString(parts[i]);
if (i + 1 < parts.Count())
this.writer.WriteRaw(" ");
}
}
// The rest of the XmlWriter methods implemented using Decorator Pattern
public override void Close()
{
this.writer.Close();
}
public override string LookupPrefix(string ns)
{
return this.writer.LookupPrefix(ns);
}
public override void Flush()
{
this.writer.Flush();
}
public override WriteState WriteState
{
get { return this.writer.WriteState; }
}
public override void WriteBase64(byte[] buffer, int index, int count)
{
this.writer.WriteBase64(buffer, index, count);
}
public override void WriteRaw(string data)
{
this.writer.WriteRaw(data);
}
public override void WriteRaw(char[] buffer, int index, int count)
{
this.writer.WriteRaw(buffer, index, count);
}
public override void WriteChars(char[] buffer, int index, int count)
{
this.writer.WriteChars(buffer, index, count);
}
public override void WriteSurrogateCharEntity(char lowChar, char highChar)
{
this.writer.WriteSurrogateCharEntity(lowChar, highChar);
}
public override void WriteWhitespace(string ws)
{
this.writer.WriteWhitespace(ws);
}
public override void WriteCharEntity(char ch)
{
this.writer.WriteCharEntity(ch);
}
public override void WriteEntityRef(string name)
{
this.writer.WriteEntityRef(name);
}
public override void WriteProcessingInstruction(string name, string text)
{
this.writer.WriteProcessingInstruction(name, text);
}
public override void WriteComment(string text)
{
this.writer.WriteComment(text);
}
public override void WriteCData(string text)
{
this.writer.WriteCData(text);
}
public override void WriteEndAttribute()
{
this.writer.WriteEndAttribute();
}
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
this.writer.WriteStartAttribute(prefix, localName, ns);
}
public override void WriteFullEndElement()
{
this.writer.WriteFullEndElement();
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
this.writer.WriteStartElement(prefix, localName, ns);
}
public override void WriteEndElement()
{
this.writer.WriteEndElement();
}
public override void WriteDocType(string name, string pubid, string sysid, string subset)
{
this.writer.WriteDocType(name, pubid, sysid, subset);
}
public override void WriteEndDocument()
{
this.writer.WriteEndDocument();
}
public override void WriteStartDocument(bool standalone)
{
this.writer.WriteStartDocument(standalone);
}
public override void WriteStartDocument()
{
this.writer.WriteStartDocument();
}
}
}