.NETでXmlDocumentからXMLを生成する場合、要素withoutに関連付けられた名前空間が最初に挿入されると、空の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
コードに適用可能な解決策はありますかafter文書をOuterXml
を使用して文字列に変換しますか?
これを行う理由は、XmlDocumentで生成されたXMLを使用して、特定のプロトコルの標準XMLと一致できるかどうかを確認することです。空白のxmlns
属性mayパーサーを壊したり混乱させたりすることはありませんが、このプロトコルで見たどのような使用法にも存在しません。
Jeremy Lewの答えともう少し遊んだおかげで、空のxmlns
属性を削除する方法を見つけました。必要な子ノードを作成するときにルートノードの名前空間を渡しますnotプレフィックスがオン。ルートで接頭辞なしの名前空間を使用すると、also接頭辞を持たないために、子要素に対して同じ名前空間を使用する必要があることを意味します。
修正コード:
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);
これにより、名前空間をどこにでもコピーまたは繰り返す必要がなくなります。
サンプルXMLの<loner>
要素に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");