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

回答:


98

宣言を明示的に書き出すか、a 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宣言のencodingがにStringWriterの符号化によって無視され、交換されることで、小さな問題が、持っている
サムホルダー

2
そして、あなたが拡張メソッドを組み合わせ:からUtf8StringWriter stackoverflow.com/a/1564727/75963 ;)
ニックJosevski

12
上記の拡張メソッドを使用する方が簡単であることがわかりましたが、次を返します... return doc.Declaration + doc.ToString(); 宣言がnullの場合、結果は空の文字列になります。
スティーブG.

奇妙ですが、今は動作しません(.net fiddle)-常に「utf-16」エンコーディングを使用しています。私はXDocument.Save(TextWriter)実装の内部を調べましたが、XDocument.Save(String)またはXDocument.Save(Stream)実装ではなく、宣言のエンコーディングを無視しています。なんでかしら…
イリヤ・ルジャイナン2015年

@IlyaLuzyanin:はい、プロパティStringWriterをオーバーライドするものを使用しない限り、を渡すとエンコーディングとして「utf-16」が使用されますEncoding。それについて別の答えがあります。「エンコーディング」を完全に削除していると言っていたと思いました...
Jon Skeet

46

Declarationプロパティには、XML宣言が含まれます。内容と宣言を取得するには、次のようにします。

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

7
xdocumentで新しいXDeclaration( "1.0"、 "utf-8"、 "yes")を使用しない場合、xml.Declarationがnullであるためエラーが発生します。しかし、xml.saveは正しいエンコーディングを自動検出するようです。
ヘンリックP.ヘッセル

またはtb_output.Text = @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + xml;
Bill Hoag 14

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()はnull例外をスローします。
ジグラー14

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"、 "yes")の代わりに新しいXDeclaration( "1.0"、 "utf-8")を使用します。2)最後の行に新しい行を挿入します:ディストリビューター。 Declaration.ToString()+ Environment.NewLine +ディストリビューター
.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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.