序列化不间断空格的选项

时间:2014-09-24 13:11:09

标签: c# xml xml-serialization

我有一个XML文档,我想加载操作然后保存回磁盘。其中一个元素的文本中包含一个不间断的空格 。当我将文档序列化后,它作为一个不间断的空间出现,但不像原来那样代码点。此问题还会影响其他代码点,例如&",但不会影响<>,因为后者在元素中不合法。您甚至不需要操纵文档来使其替换字符。

有没有办法让它作为代码点序列化? 文件示例

<Node>
<InnerNode>Some&#160;Text</InnerNode>
</Node>

代码示例

XmlDocument doc = new XmlDocument {PreserveWhitespace = true};
doc.Load(fileStream.BaseStream);
doc.Save(path);

1 个答案:

答案 0 :(得分:1)

您的目标可以通过使用decorated XmlWriter对象来实现。下面的代码用&#160;方法中的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("&#160;");
            }
        }

        // 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();
        }
    }
}