Как распечатать <? Xml version = "1.0"?> С помощью XDocument - PullRequest
60 голосов
/ 05 июня 2009

Есть ли способ заставить XDocument распечатать версию XML при использовании метода ToString? Пусть он выведет что-то вроде этого:

<?xml version="1.0"?>
<!DOCTYPE ELMResponse [
]>
<Response>
<Error> ...

У меня есть следующее:

var xdoc = new XDocument(new XDocumentType("Response", null, null, "\n"), ...

, который напечатает это нормально, но в нем отсутствует «<? Xml версия», как указано выше. </p>

<!DOCTYPE ELMResponse [
]>
<Response>
<Error> ...

Я знаю, что вы можете сделать это, выдав это вручную самостоятельно. Просто хотел узнать, возможно ли это с помощью XDocument.

Ответы [ 5 ]

107 голосов
/ 05 июня 2009

С помощью 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());
13 голосов
/ 02 декабря 2010

На данный момент это лучший и наиболее управляемый способ:

var xdoc = new XDocument(new XElement("Root", new XElement("Child", "台北 Táibě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());
    }
}

и я говорю это только потому, что вы можете изменить кодировку на что угодно, изменив .UTF8 на .Unicode или .UTF32

3 голосов
/ 16 ноября 2018

Поздний ответ на старый вопрос, но я постараюсь предоставить больше деталей, чем другие ответы.

То, о чем вы спрашиваете, называется декларация XML .

Прежде всего, XDocument имеет свойство Declaration типа XDeclaration для этого. Вы можете использовать другую перегрузку конструктора XDocument:

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

или установите свойство позже:

xdoc.Declaration = new XDeclaration("1.0", null, null);

Но в зависимости от того, как вы сохраните или напишите свой 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")

Обратите внимание, что 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}";

Некоторые другие ответы показывают, что XDeclaration будет соблюдаться, если вы используете xdoc.Save или xdoc.WriteTo методы, но это не совсем так:

  • Они могут включать декларацию XML, даже если у вас ее нет в XDocument
  • Они могут указывать кодировку, используемую целевым файлом, потоком, записывающим устройством, сборщиком строк и т. Д. Вместо кодировки, которую вы указали, или вместо пропуска кодировки, если вы сделали это в вашем XDeclaration
  • Они могут изменить вашу версию, например, с 1.1 в 1.0

Конечно, когда вы сохраняете / записываете в файл, хорошо, что объявление соответствует истинной кодировке этого файла!

Но иногда, когда вы пишете строку в памяти, вам не нужен utf-16 (даже если вы понимаете, что строки .NET находятся внутри UTF-16). Вы можете использовать метод расширения выше. Или вы можете использовать следующую взломанную версию метода из ответа EricSch:

  string xdocString;
  using (var hackedWriter = new SuppressEncodingStringWriter())
  {
    xdoc.Save(hackedWriter);
    xdocString = hackedWriter.ToString();
  }

где у вас есть:

// 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;
}
2 голосов
/ 05 июня 2009

Просто введите это

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

И вы получите

<?xml version="1.0" encoding="utf-16" standalone="no"?>
<blah>blih</blah>
0 голосов
/ 06 декабря 2012

КОД РЕШЕНИЯ VB.NET

код

   Dim _root As XElement = <root></root>
   Dim _element1 As XElement = <element1>i am element one</element1>
   Dim _element2 As XElement = <element2>i am element one</element2>
   _root.Add(_element1)
   _root.Add(_element2)
   Dim _document As New XDocument(New XDeclaration("1.0", "UTF-8", "yes"), _root)
   _document.Save("c:\xmlfolder\root.xml")

Вывод Примечание (откройте вывод в блокноте)

 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <root>
   <element1>i am element one</element1>
   <element2>i am element one</element2>
</root>
...