125

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

4

7 に答える 7

116

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

私を正しい方向に導いてくれたすべての回答に感謝します!

于 2008-09-25T20:49:13.163 に答える
96

これは、JeniT の回答の変形です (どうもありがとうございました!)

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

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

于 2011-12-30T04:02:18.487 に答える
11

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

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

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

于 2008-09-25T18:23:02.640 に答える
7

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

<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);
于 2008-09-25T18:27:59.023 に答える
0

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);
    }
}
于 2011-02-23T16:30:21.053 に答える
0

はい、 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");
于 2015-06-06T17:56:24.100 に答える
0

可能であれば、シリアライゼーション クラスを作成してから、次の操作を行います。

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

そのほうが安全です。さらに制御が必要な場合は、属性を使用して名前空間を制御できます。

于 2008-09-25T19:40:30.503 に答える