如何使用XDocument打印<?xml version ="1.0"?>

JD *_*ias 61 c# xml linq-to-xml

有没有办法让XDocument在使用ToString方法时打印xml版本?输出这样的东西:

<?xml version="1.0"?>
<!DOCTYPE ELMResponse [
]>
<Response>
<Error> ...
Run Code Online (Sandbox Code Playgroud)

我有以下内容:

var xdoc = new XDocument(new XDocumentType("Response", null, null, "\n"), ...
Run Code Online (Sandbox Code Playgroud)

这将打印出这个很好的,但它缺少如上所述的"<?xml版本".

<!DOCTYPE ELMResponse [
]>
<Response>
<Error> ...
Run Code Online (Sandbox Code Playgroud)

我知道你可以通过手动输出我自己来做到这一点.只是想知道是否可以使用XDocument.

Eri*_*Sch 110

通过使用XDeclaration.这将添加声明.

但是ToString()你不会得到所需的输出.

你需要使用XDocument.Save()他的一种方法.

完整样本:

var doc = new XDocument(
        new XDeclaration("1.0", "utf-16", "yes"), 
        new XElement("blah", "blih"));

var wr = new StringWriter();
doc.Save(wr);
Console.Write(wr.ToString());
Run Code Online (Sandbox Code Playgroud)

  • 简单的wr.toString()工作,不需要在它们之间有GetStringBuilder() (3认同)
  • 你是对的,当他说他正在使用ToString()时,我错过了这个部分.因此,使用XDeclaration和Save()(到文件或内存流). (2认同)
  • 提示:您可以创建一个扩展方法来将功能添加到`ToString`方法.例如`public static string ToString(this XDocument doc,bool addDeclaration)` (2认同)

小智 14

这是迄今为止最好的方式和最可管理的方式:

var xdoc = new XDocument(new XElement("Root", new XElement("Child", "?? Ta?ibe?i.")));

string mystring;

using(var sw = new MemoryStream())
{
    using(var strw = new StreamWriter(sw, System.Text.UTF8Encoding.UTF8))
    {
         xdoc.Save(strw);
         mystring = System.Text.UTF8Encoding.UTF8.GetString(sw.ToArray());
    }
}
Run Code Online (Sandbox Code Playgroud)

我说这只是因为你可以通过将.UTF8改为.Unicode或.UTF32来改变编码


Jep*_*sen 7

对一个旧问题的较晚答案,但是我将尝试提供比其他答案更多的细节。

您要问的事情称为XML声明

首先,XDocument对此具有Declaration类型的属性XDeclaration。您可以使用XDocument构造函数的另一个重载:

var xdoc = new XDocument(
  new XDeclaration("1.0", null, null), // <--- here
  new XDocumentType("Response", null, null, "\n"), ... 
  );
Run Code Online (Sandbox Code Playgroud)

或稍后设置属性:

xdoc.Declaration = new XDeclaration("1.0", null, null);
Run Code Online (Sandbox Code Playgroud)

但是根据您以后保存编写内容的方式XDocument,声明(或其一部分)可能会被忽略。以后再说。

XML声明可以有多种外观。以下是一些有效的示例:

<?xml version="1.0"?>                                        new XDeclaration("1.0", null, null)
<?xml version="1.1"?>                                        new XDeclaration("1.1", null, null)
<?xml version="1.0" encoding="us-ascii"?>                    new XDeclaration("1.0", "us-ascii", null)
<?xml version="1.0" encoding="utf-8"?>                       new XDeclaration("1.0", "utf-8", null)
<?xml version="1.0" encoding="utf-16"?>                      new XDeclaration("1.0", "utf-16", null)
<?xml version="1.0" encoding="utf-8" standalone="no"?>       new XDeclaration("1.0", "utf-8", "no")
<?xml version="1.0" encoding="utf-8" standalone="yes"?>      new XDeclaration("1.0", "utf-8", "yes")
<?xml version="1.0" standalone="yes"?>                       new XDeclaration("1.0", null, "yes")
Run Code Online (Sandbox Code Playgroud)

请注意,XDeclaration它将很乐意接受无效的参数,因此,正确的选择取决于您。

在许多情况下<?xml version="1.0"?>,您要求的第一个表单是完美的(不需要给出encoding它是否只是UTF-8(包括ASCII),也不需要指定standalone其预期值"no"是否存在或是否存在)。没有DTD)。

请注意,xdoc.ToString()它会从XNode基类(在我的.NET版本中)进行覆盖,并且不包含XML声明。您可以轻松地创建一个处理该问题的方法,如下所示:

public static string ToStringWithDecl(this XDocument d)
  => $"{d.Declaration}{Environment.NewLine}{d}";
Run Code Online (Sandbox Code Playgroud)

其他一些答案表明,XDeclaration如果您使用xdoc.Savexdoc.WriteTo方法,将尊重,但事实并非如此:

  • 它们可能包含XML声明,即使您没有 XDocument
  • 他们可能指定目标文件,流,编写器,字符串生成器等使用的编码,而不是您指定的编码,或者如果您在自己的编码中指定了编码,则不要省略 XDeclaration
  • 他们可能会将您的版本从例如更改1.11.0

当然,当您保存/写入文件时,声明与该文件的真实编码匹配是一件好事!

但是有时候,当您在内存中写入字符串时,您并不需要utf-16(即使您意识到.NET字符串内部在UTF-16中)。您可以改用上面的扩展方法。或者,您可以从EricSch的答案中使用该方法的以下修改版本:

  string xdocString;
  using (var hackedWriter = new SuppressEncodingStringWriter())
  {
    xdoc.Save(hackedWriter);
    xdocString = hackedWriter.ToString();
  }
Run Code Online (Sandbox Code Playgroud)

您在哪里:

// a string writer which claims its encoding is null in order to omit encoding in XML declarations
class SuppressEncodingStringWriter : StringWriter
{
  public sealed override Encoding Encoding => null;
}
Run Code Online (Sandbox Code Playgroud)