XDocument.ToString()删除XML编码标签


103

有什么方法可以在toString()函数中获取xml编码吗?

例:

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>
    ...

Answers:


98

显式写出声明,或使用StringWriterand调用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 2010年

2
然后,将扩展方法与以下各项组合:来自stackoverflow.com/a/1564727/75963的 Utf8StringWriter ;)
Nick Josevski 2012年

12
发现使用上面的扩展方法更容易,但是返回以下内容... return doc.Declaration + doc.ToString(); 如果声明为空,则只会导致一个空字符串。
史蒂夫·G.

奇怪,但是我现在无法正常运行(.net fiddle)-它始终使用“ utf-16”编码。我看着里面XDocument.Save(TextWriter)的实现,它只是忽略了声明的编码,而不是XDocument.Save(String)XDocument.Save(Stream)实现。我不知道为什么...
Ilya Luzyanin

@IlyaLuzyanin:是的,当您传入时,它将使用“ utf-16”作为编码StringWriter,除非您使用一个覆盖该Encoding属性的编码。我对此有另一个答案。我以为您是说它完全放弃了“编码” ...
Jon Skeet

46

声明属性将包含XML声明。要获取内容加上声明,可以执行以下操作:

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

7
似乎如果您不在xdocument中使用新的XDeclaration(“ 1.0”,“ utf-8”,“ yes”),则会造成错误,因为xml.Declaration为null。但是xml.save似乎可以自动检测正确的编码。
Henrik P. Hessel

tb_output.Text = @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + xml;
Bill Hoag 2014年

4
... = $"{xdoc.Declaration}{Environment.NewLine}{xdoc}";
WernerCD '17

9

用这个:

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

2
如果不创建新的XDeclaration(“ 1.0”,“ utf-8”,“ yes”)并将其添加到XDocument或其他对象中,则xml.Declaration.ToString()将引发null异常。
Ziggler 2014年

1
像下面这样更安全,因为Concat不在乎空字符串:output.Text = String.Concat(xml.Declaration,xml)
dmihailescu 2015年

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)使用new XDeclaration(“ 1.0”,“ utf-8”)代替new XDeclaration(“ 1.0”,“ utf-8”,“ yes”),2)在最后一行中插入新行:分发服务器。 Declaration.ToString()+ Environment.NewLine + distributors.ToString()
阿列克谢·奥布霍夫

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.