XDocument.ToString () bỏ Thẻ mã hóa XML


103

Có cách nào để lấy mã hóa xml trong hàm toString () không?

Thí dụ:

xml.Save("myfile.xml");

dẫn đến

<?xml version="1.0" encoding="utf-8"?>
<Cooperations>
  <Cooperation>
    <CooperationId>xxx</CooperationId>
    <CooperationName>Allianz Konzern</CooperationName>
    <LogicalCustomers>

Nhưng

tb_output.Text = xml.toString();

dẫn đến một đầu ra như thế này

<Cooperations>
  <Cooperation>
    <CooperationId>xxx</CooperationId>
    <CooperationName>Allianz Konzern</CooperationName>
    <LogicalCustomers>
    ...

Câu trả lời:


98

Viết khai báo một cách rõ ràng hoặc sử dụng StringWritervà gọi Save():

using System;
using System.IO;
using System.Text;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        string xml = @"<?xml version='1.0' encoding='utf-8'?>
<Cooperations>
  <Cooperation />
</Cooperations>";

        XDocument doc = XDocument.Parse(xml);
        StringBuilder builder = new StringBuilder();
        using (TextWriter writer = new StringWriter(builder))
        {
            doc.Save(writer);
        }
        Console.WriteLine(builder);
    }
}

Bạn có thể dễ dàng thêm nó làm phương thức mở rộng:

public static string ToStringWithDeclaration(this XDocument doc)
{
    if (doc == null)
    {
        throw new ArgumentNullException("doc");
    }
    StringBuilder builder = new StringBuilder();
    using (TextWriter writer = new StringWriter(builder))
    {
        doc.Save(writer);
    }
    return builder.ToString();
}

Điều này có ưu điểm là nó sẽ không đi nổ nếu có không phải là một tuyên bố :)

Sau đó, bạn có thể sử dụng:

string x = doc.ToStringWithDeclaration();

Lưu ý rằng điều đó sẽ sử dụng utf-16 làm mã hóa, vì đó là mã hóa ngầm trong StringWriter. Mặc dù vậy, bạn có thể tác động đến điều đó bằng cách tạo một lớp con StringWriter, ví dụ: luôn sử dụng UTF-8 .


14
Này có một vấn đề nhỏ trong đó các mã hóa trong tờ khai XDocument được bỏ qua và thay thế bằng mã hóa của StringWriter khi thực hiện tiết kiệm, mà có thể hoặc không thể là những gì bạn muốn
Sam Chủ

2
Sau đó, bạn kết hợp phương thức mở rộng với: Utf8StringWriter từ stackoverflow.com/a/1564727/75963 ;)
Nick Josevski

12
Thấy dễ dàng hơn khi sử dụng phương thức mở rộng ở trên nhưng trả về như sau ... return doc.Decosystem + doc.ToString (); Nếu Tuyên bố là null, nó chỉ dẫn đến một chuỗi trống.
Steve G.

Kỳ lạ, nhưng tôi không thể làm cho nó hoạt động ngay bây giờ ( .net fiddle ) - nó luôn sử dụng mã hóa "utf-16". Tôi đã xem xét bên trong XDocument.Save(TextWriter)triển khai và nó chỉ bỏ qua mã hóa của khai báo, trái ngược với XDocument.Save(String)hoặc XDocument.Save(Stream)triển khai. Tôi tự hỏi tại sao ...
Ilya Luzyanin

@IlyaLuzyanin: Có, nó sẽ sử dụng "utf-16" làm mã hóa khi bạn chuyển vào a StringWriter, trừ khi bạn sử dụng mã ghi đè thuộc Encodingtính. Tôi có một câu trả lời khác về điều đó. Tôi nghĩ bạn đang nói nó đã được thả "mã hóa" hoàn toàn ...
Jon Skeet

46

Thuộc tính Khai báo sẽ chứa khai báo XML. Để lấy nội dung cộng với khai báo, bạn có thể làm như sau:

tb_output.Text = xml.Declaration.ToString() + xml.ToString()

7
Có vẻ như nếu bạn không sử dụng XDec Tuyên bố mới ("1.0", "utf-8", "có") trong xdocument của bạn, điều này sẽ tạo ra lỗi vì xml.Dec Tuyên bố là null. Nhưng xml.save dường như tự động phát hiện mã hóa phù hợp.
Henrik P. Hessel

hoặc,tb_output.Text = @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + xml;
Bill Hoag

4
hoặc... = $"{xdoc.Declaration}{Environment.NewLine}{xdoc}";
WernerCD 14/12/17

9

dùng cái này:

output.Text = String.Concat(xml.Declaration.ToString() , xml.ToString())

2
Nếu không tạo XDecloy mới ("1.0", "utf-8", "yes") và thêm vào XDocument hoặc đối tượng khác, xml.Decosystem.ToString () sẽ ném ra một ngoại lệ rỗng.
Ziggler

1
đó là an toàn hơn như dưới đây vì concat không quan tâm đến chuỗi null: output.Text = String.Concat (xml.Declaration, xml)
dmihailescu

3

Tôi đã làm như thế này

        string distributorInfo = string.Empty;

        XDocument distributors = new XDocument();

     //below is important else distributors.Declaration.ToString() throws null exception
        distributors.Declaration = new XDeclaration("1.0", "utf-8", "yes"); 

        XElement rootElement = new XElement("Distributors");
        XElement distributor = null;
        XAttribute id = null;

        distributor = new XElement("Distributor");
        id = new XAttribute("Id", "12345678");
        distributor.Add(id);
        rootElement.Add(distributor);

        distributor = new XElement("Distributor");
        id = new XAttribute("Id", "22222222");

        distributor.Add(id);

        rootElement.Add(distributor);         

        distributors.Add(rootElement);

        distributorInfo = String.Concat(distributors.Declaration.ToString(), distributors.ToString());

Vui lòng xem bên dưới để biết những gì tôi nhận được trong nhà phân phốiInfo

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Distributors>
  <Distributor Id="12345678" />
  <Distributor Id="22222222" />
  <Distributor Id="11111111" />
</Distributors>

1
ví dụ tốt. một số lưu ý: 1) sử dụng XDec Tuyên bố mới ("1.0", "utf-8") thay vì XDec Tuyên bố mới ("1.0", "utf-8", "có"), 2) chèn dòng mới vào dòng cuối cùng: nhà phân phối. Declaration.ToString () + Environment.NewLine + distributors.ToString ()
Alexey Obukhov

2

Tương tự với các câu trả lời +1 khác, nhưng chi tiết hơn một chút về khai báo và nối chính xác hơn một chút.

<xml />khai báo phải nằm trên dòng riêng của nó trong một định dạng XML, vì vậy tôi đảm bảo rằng chúng tôi đã thêm dòng mới. LƯU Ý: sử dụng Environment.Newlinenhư vậy nó sẽ tạo ra dòng mới cụ thể cho nền tảng

// Parse xml declaration menthod
XDocument document1 =
  XDocument.Parse(@"<?xml version=""1.0"" encoding=""iso-8859-1""?><rss version=""2.0""></rss>");
string result1 =
  document1.Declaration.ToString() +
  Environment.NewLine +
  document1.ToString() ;

// Declare xml declaration method
XDocument document2 = 
  XDocument.Parse(@"<rss version=""2.0""></rss>");
document2.Declaration =
  new XDeclaration("1.0", "iso-8859-1", null);
string result2 =
  document2.Declaration.ToString() +
  Environment.NewLine +
  document2.ToString() ;

Cả hai kết quả đều tạo ra:

<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0"></rss>

1

Một vài câu trả lời trong số này giải quyết được yêu cầu của người đăng, nhưng có vẻ quá phức tạp. Đây là một phương thức mở rộng đơn giản giúp tránh yêu cầu trình viết riêng, xử lý khai báo bị thiếu và hỗ trợ tham số ToString SaveOptions tiêu chuẩn.

public static string ToXmlString(this XDocument xdoc, SaveOptions options = SaveOptions.None)
{
    var newLine =  (options & SaveOptions.DisableFormatting) == SaveOptions.DisableFormatting ? "" : Environment.NewLine;
    return xdoc.Declaration == null ? xdoc.ToString(options) : xdoc.Declaration + newLine + xdoc.ToString(options);
}

Để sử dụng tiện ích mở rộng, chỉ cần thay thế xml.ToString()bằngxml.ToXmlString()


0

Bạn cũng có thể sử dụng XmlWriter và gọi

Writer.WriteDocType() 

phương pháp.


0
string uploadCode = "UploadCode";
string LabName = "LabName";
XElement root = new XElement("TestLabs");
foreach (var item in returnList)
{  
       root.Add(new XElement("TestLab",
                new XElement(uploadCode, item.UploadCode),
                new XElement(LabName, item.LabName)
                            )
               );
}

XDocument returnXML = new XDocument(new XDeclaration("1.0", "UTF-8","yes"),
             root);

string returnVal;
using (var sw = new MemoryStream())
{
       using (var strw = new StreamWriter(sw, System.Text.UTF8Encoding.UTF8))
       {
              returnXML.Save(strw);
              returnVal = System.Text.UTF8Encoding.UTF8.GetString(sw.ToArray());
       }
}

// ReturnVal has the string with XML data with XML declaration tag
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.