.NET の XmlDocument からの出力に空の xmlns 属性が含まれないようにするにはどうすればよいですか?
-
02-07-2019 - |
質問
.NET で XmlDocument から XML を生成する場合、空白 xmlns
要素が初めて出現するときに属性 それなし 関連する名前空間が挿入されます。どうすればこれを防ぐことができるでしょうか?
例:
XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root",
"whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner"));
Console.WriteLine(xml.OuterXml);
出力:
<root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root>
望ましい 出力:
<root xmlns="whatever:name-space-1.0"><loner /></root>
に適用できる解決策はありますか XmlDocument
コード、発生するものではない 後 ドキュメントを文字列に変換する OuterXml
?
これを行う理由は、XmlDocument で生成された XML を使用して、特定のプロトコルの標準 XML と一致できるかどうかを確認するためです。ブランク xmlns
属性 5月 パーサーを壊したり混乱させたりすることはありませんが、私がこのプロトコルについて見たどの使用法にも存在しません。
解決
Jeremy Lew の答えともう少し遊んだおかげで、空白を削除する方法がわかりました xmlns
属性:必要な子ノードを作成するときにルート ノードの名前空間を渡します ない プレフィックスを付けるには。ルートでプレフィックスのない名前空間を使用するということは、子要素で同じ名前空間を使用する必要があることを意味します。 また プレフィックスがありません。
修正されたコード:
XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0"));
Console.WriteLine(xml.OuterXml);
私を正しい方向に導いてくれたすべての回答に感謝します。
他のヒント
これは JeniT の回答の変形です (ところで、本当にありがとうございます!)
XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);
これにより、名前空間をどこにでもコピーしたり繰り返したりする必要がなくなります。
もし <loner>
サンプル XML の要素には xmlns
デフォルトの名前空間宣言がある場合、それは whatever:name-space-1.0
名前空間に存在しないのではなく、名前空間を使用します。それが必要な場合は、その名前空間に要素を作成する必要があります。
xml.CreateElement("loner", "whatever:name-space-1.0")
ご希望の場合は、 <loner>
要素が名前空間に存在しない場合、生成される XML はまさに必要なものであり、 xmlns
自動的に追加された属性。
ルートはプレフィックスのない名前空間にあるため、名前空間を解除したいルートの子は、例のように出力する必要があります。解決策は、次のようにルート要素にプレフィックスを付けることです。
<w:root xmlns:w="whatever:name-space-1.0">
<loner/>
</w:root>
コード:
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement( "w", "root", "whatever:name-space-1.0" );
doc.AppendChild( root );
root.AppendChild( doc.CreateElement( "loner" ) );
Console.WriteLine(doc.OuterXml);
可能であれば、シリアル化クラスを作成して、次の操作を実行します。
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);
これはより安全であり、さらに詳細な制御が必要な場合は、属性を使用して名前空間を制御できます。
Factory Patternを使用することで問題を解決しました。XElement オブジェクトのファクトリーを作成しました。ファクトリのインスタンス化のパラメータとして、XNamespace オブジェクトを指定しました。したがって、XElement がファクトリによって作成されるたびに、名前空間が自動的に追加されます。ファクトリーのコードは次のとおりです。
internal class XElementFactory
{
private readonly XNamespace currentNs;
public XElementFactory(XNamespace ns)
{
this.currentNs = ns;
}
internal XElement CreateXElement(String name, params object[] content)
{
return new XElement(currentNs + name, content);
}
}
はい、 XmlElement からの XMLNS を防ぐことができます。初めての作成時間が近づいています:そのように
<trkpt lat="30.53597" lon="-97.753324" xmlns="">
<ele>249.118774</ele>
<time>2006-05-05T14:34:44Z</time>
</trkpt>
コードを変更します:このようなXMLネームスペースを渡します
C# コード:
XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");