web-dev-qa-db-ja.com

.NETのXmlDocumentからの出力で空のxmlns属性を防ぐ方法は?

.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パーサーを壊したり混乱させたりすることはありませんが、このプロトコルで見たどのような使用法にも存在しません。

112

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);

正しい方向に私を導いたあなたのすべての答えにみんなに感謝します!

103

これはJeniTの回答の一種です(ありがとうございました!)

XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);

これにより、名前空間をどこにでもコピーまたは繰り返す必要がなくなります。

82
C Johnson

サンプルXMLの<loner>要素にxmlnsデフォルト名前空間宣言が含まれていない場合、名前空間がないのではなく、whatever:name-space-1.0名前空間にあります。それが必要な場合は、その名前空間に要素を作成する必要があります。

xml.CreateElement("loner", "whatever:name-space-1.0")

<loner>要素を名前空間なしにしたい場合、生成されるXMLはまさに必要なものであり、自動的に追加されるxmlns属性について心配する必要はありません。

10
JeniT

ルートは接頭辞のない名前空間にあるため、名前空間を解除したいルートの子は、例のように出力する必要があります。解決策は、次のようにルート要素にプレフィックスを付けることです。

<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);
7
jlew

可能であれば、シリアル化クラスを作成してから以下を実行します。

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);

より安全であり、本当に制御が必要な場合は、属性を使用して名前空間を制御できます。

0
ilitirit

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);
    }
}
0
brinke

はい、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");
0
Debabrata Ghosh