XDocument ToString () ลดแท็กการเข้ารหัส XML


104

มีวิธีใดบ้างในการรับการเข้ารหัส xml ในฟังก์ชัน toString ()

ตัวอย่าง:

xml.Save("myfile.xml");

นำไปสู่

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

แต่

tb_output.Text = xml.toString();

นำไปสู่ผลลัพธ์เช่นนี้

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

คำตอบ:


99

เขียนคำประกาศอย่างชัดเจนหรือใช้StringWriterและโทร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);
    }
}

คุณสามารถเพิ่มสิ่งนั้นเป็นวิธีการขยายได้อย่างง่ายดาย:

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

นี่มีข้อดีคือมันจะไม่ปังถ้าไม่มีประกาศ :)

จากนั้นคุณสามารถใช้:

string x = doc.ToStringWithDeclaration();

โปรดทราบว่าจะใช้ utf-16 เป็นการเข้ารหัสเนื่องจากเป็นการเข้ารหัสโดยนัยในรูปแบบStringWriter. คุณสามารถสร้างอิทธิพลต่อตัวเองได้ด้วยการสร้างคลาสย่อยStringWriterเช่นใช้ UTF-8เสมอ


14
สิ่งนี้มีปัญหาเล็กน้อยที่การเข้ารหัสในการประกาศ XDocument จะถูกละเว้นและถูกแทนที่ด้วยการเข้ารหัสของ StringWriter เมื่อทำการบันทึกซึ่งอาจใช่หรือไม่ใช่สิ่งที่คุณต้องการ
Sam Holder

2
จากนั้นคุณรวมวิธีการขยายด้วย: Utf8StringWriter จากstackoverflow.com/a/1564727/75963 ;)
Nick Josevski

12
พบว่าง่ายกว่าที่จะใช้วิธีการขยายด้านบน แต่ส่งคืนสิ่งต่อไปนี้ ... กลับ doc.Declaration + doc ToString (); หากการประกาศเป็นโมฆะจะส่งผลให้สตริงว่างเปล่า
Steve G.

แปลก แต่ตอนนี้ใช้งานไม่ได้ ( .net fiddle ) - มันใช้การเข้ารหัส "utf-16" เสมอ ฉันได้ตรวจสอบXDocument.Save(TextWriter)การใช้งานภายในแล้วและเพียงแค่เพิกเฉยต่อการเข้ารหัสของการประกาศซึ่งตรงข้ามกับXDocument.Save(String)หรือXDocument.Save(Stream)การใช้งาน ฉันสงสัยว่าทำไม ...
Ilya Luzyanin

@IlyaLuzyanin: ใช่มันจะใช้ "utf-16" เป็นตัวเข้ารหัสเมื่อคุณผ่านใน a StringWriterเว้นแต่คุณจะใช้อันที่แทนที่Encodingคุณสมบัติ ฉันมีคำตอบอื่นเกี่ยวกับเรื่องนี้ ฉันคิดว่าคุณกำลังพูดว่ากำลัง "เข้ารหัส" ทิ้งไปทั้งหมด ...
Jon Skeet

46

คุณสมบัติการประกาศจะมีการประกาศ XML ในการรับเนื้อหาพร้อมการประกาศคุณสามารถดำเนินการดังต่อไปนี้:

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

7
ดูเหมือนว่าถ้าคุณไม่ใช้ XDeclaration ใหม่ ("1.0", "utf-8", "yes") ใน xdocument สิ่งนี้จะสร้างข้อผิดพลาดเนื่องจาก xml การประกาศเป็นโมฆะ แต่ xml.save ดูเหมือนจะตรวจจับการเข้ารหัสที่ถูกต้องโดยอัตโนมัติ
Henrik P. Hessel

หรือtb_output.Text = @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + xml;
Bill Hoag

4
หรือ... = $"{xdoc.Declaration}{Environment.NewLine}{xdoc}";
WernerCD

9

ใช้สิ่งนี้:

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

2
โดยไม่ต้องสร้าง XDeclaration ใหม่ ("1.0", "utf-8", "yes") และเพิ่มลงใน XDocument หรืออ็อบเจ็กต์อื่น xml.Declaration ToString () จะทำให้เกิดข้อยกเว้นที่เป็นโมฆะ
Ziggler

1
ปลอดภัยกว่าเช่นด้านล่างเพราะ Concat ไม่สนใจสตริง null: output.Text = String.Concat (xml.Declaration, xml)
dmihailescu

3

ฉันทำแบบนี้

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

โปรดดูสิ่งที่ฉันได้รับจาก DistributorInfo ด้านล่าง

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

1
ตัวอย่างที่ดี หมายเหตุบางประการ: 1) ใช้ XDeclaration ใหม่ ("1.0", "utf-8") แทน XDeclaration ใหม่ ("1.0", "utf-8", "yes"), 2) แทรกบรรทัดใหม่ในบรรทัดสุดท้าย: ผู้จัดจำหน่าย Declaration ToString () + Environment.NewLine + ผู้จัดจำหน่าย ToString ()
Alexey Obukhov

2

คล้ายกับคำตอบ +1 อื่น ๆ แต่มีรายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับการประกาศและการเรียงต่อกันที่แม่นยำกว่าเล็กน้อย

<xml />การประกาศควรอยู่ในบรรทัดของตัวเองใน XML ที่จัดรูปแบบดังนั้นฉันจึงแน่ใจว่าเราได้เพิ่มบรรทัดใหม่แล้ว หมายเหตุ: การใช้Environment.Newlineมันจะสร้างบรรทัดใหม่เฉพาะแพลตฟอร์ม

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

ผลลัพธ์ทั้งสองให้ผลลัพธ์:

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

1

คำตอบสองสามข้อนี้ช่วยแก้คำขอของผู้โพสต์ แต่ดูเหมือนจะซับซ้อนเกินไป ต่อไปนี้เป็นวิธีการขยายอย่างง่ายที่หลีกเลี่ยงความจำเป็นในการเขียนแยกต่างหากจัดการกับการประกาศที่ขาดหายไปและรองรับพารามิเตอร์ ToString SaveOptions มาตรฐาน

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

หากต้องการใช้ส่วนขยายให้แทนที่xml.ToString()ด้วยxml.ToXmlString()



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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.