XDocument 获取包括第一行的声明(版本、编码)的所有节点

XDocument保存为xml文件的方法如下:

XDocument doc = new XDocument(
    new XDeclaration("1.0","UTF-8",null),
    new XElement("Persons",                         
        new XElement("Person",
            new XAttribute("id","1"),
            new XElement("Name","张三"),
            new XElement("Age",18)
        )                  
    )
    );
doc.Save("person.xml");
View Code

person.xml打开时有第一行的版本和编码声明:

<?xml version="1.0" encoding="utf-8"?>
<Persons>
  <Person id="1">
    <Name>张三</Name>
    <Age>18</Age>
  </Person>
</Persons>

但是有时不想保存为文件,直接获取上面内容为保存在一个string中:

string xml = doc.ToString();

此时xml的值为下面,获取不到xml第一行的声明:

<Persons>
  <Person id="1">
    <Name>张三</Name>
    <Age>18</Age>
  </Person>
</Persons>

解决方法有几种:

第1种,比较简单:

string xml = doc.Declaration.ToString() + doc.ToString();

第2种,写个扩展方法

 public static string ToStringWithDeclaration(this XDocument doc, SaveOptions options = SaveOptions.DisableFormatting)
        {
            return doc.Declaration.ToString() + doc.ToString(options);
        }

调用:

string xml = doc.ToStringWithDeclaration();

第3种,同样写个扩展方法封装起来

public static string ToStringWithDeclaration(this XDocument doc)
       {
           StringBuilder sb = new StringBuilder();
           using (TextWriter tw = new StringWriter(sb))
           {               
               doc.Save(tw, SaveOptions.DisableFormatting);
           }         
           return sb.ToString();
       }

这种方法有个问题是生成的编码声明变成了encoding="utf-16",要想换成encoding="utf-8"可
写个类Utf8StringWriter继承StringWriter,并设置重载属性Encoding为UTF8,完整代码如下

 public class Utf8StringWriter : StringWriter
        {
            public Utf8StringWriter(StringBuilder sb) : base(sb){ }
            public override Encoding Encoding { get { return Encoding.UTF8; } }
        }
       public static string ToStringWithDeclaration(this XDocument xdoc)
       {
           StringBuilder sb = new StringBuilder();
           using (TextWriter tw = new Utf8StringWriter(sb))
           {   
               xdoc.Save(tw, SaveOptions.DisableFormatting);
           }
           return sb.ToString();
       }
View Code

备注:
XDocument.ToString 方法有2个重载列表,可以设置XML节点是否缩进

名称    说明
ToString()     返回此节点的缩进 XML。
ToString(SaveOptions)     返回此节点的 XML,还可以选择禁用格式设置。

SaveOptions有两个枚举值:
   DisableFormatting 不缩进
   None 缩进

XDocument.Save 方法也有个参数SaveOptions可以设置。

参考文章:
http://msdn.microsoft.com/zh-cn/library/vstudio/bb538297%28v=vs.90%29.aspx
http://stackoverflow.com/questions/1228976/xdocument-tostring-drops-xml-encoding-tag
http://stackoverflow.com/questions/5248400/why-does-the-xdocument-give-me-a-utf16-declaration

原文地址:https://www.cnblogs.com/gdjlc/p/3313713.html