ToStringメソッドを使用するときにXDocumentにxmlバージョンを印刷させる方法はありますか?次のように出力します:
_<?xml version="1.0"?>
<!DOCTYPE ELMResponse [
]>
<Response>
<Error> ...
_
私は次のものを持っています:
var xdoc = new XDocument(new XDocumentType("Response", null, null, "\n"), ...
これは問題ありませんが、上記の「<?xmlバージョン」が欠落しています。
_<!DOCTYPE ELMResponse [
]>
<Response>
<Error> ...
_
私は自分で手動で出力することでこれができることを知っています。 XDocumentを使用してそれが可能かどうかを知りたかっただけです。
XDeclarationを使用します。これにより、宣言が追加されます。
ただし、ToString()
では、目的の出力が得られません。
彼のメソッドの1つで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());
これは断然最良の方法であり、最も管理しやすいものです。
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に変更することで、エンコーディングを何にでも変更できるからです。
古い質問に対する遅い答えですが、他の答えよりも詳細を提供するようにします。
あなたが尋ねることは、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);
_
ただし、saveまたはwriteXDocument
後で、宣言(またはその一部)は無視される場合があります。それについては後で詳しく説明します。
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"?>
_は完璧です(UTF-8(ASCIIを含む)である場合はencoding
を与える必要はありません。目的の値が_"no"
_の場合、またはDTDがない場合はstandalone
を指定する必要があります)。
xdoc.ToString()
はXNode
基本クラス(.NETのバージョン)からオーバーライドを行い、XML宣言を含まないことに注意してください。次のように、それを処理するメソッドを簡単に作成できます。
_public static string ToStringWithDecl(this XDocument d)
=> $"{d.Declaration}{Environment.NewLine}{d}";
_
_xdoc.Save
_メソッドまたは_xdoc.WriteTo
_メソッドを使用する場合、XDeclaration
が尊重されることを他の回答のいくつかは示していますが、それはまったく正しくありません。
XDocument
にXML宣言がない場合でも、XML宣言が含まれる場合がありますXDeclaration
でエンコーディングを省略した場合は、ターゲットファイル、ストリーム、ライター、文字列ビルダーなどで使用されるエンコーディングを指定する場合があります。1.1
_から_1.0
_へもちろん、ファイルに保存/書き込みするとき、宣言がそのファイルの真のエンコーディングと一致するのは良いことです!
ただし、mememoryの文字列に書き込むときに、_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;
}
_
これを入力してください
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>
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>