【问题标题】:How do I add multiple namespaces to the root element with XmlDocument?如何使用 XmlDocument 向根元素添加多个命名空间?
【发布时间】:2010-09-24 19:10:05
【问题描述】:

我需要创建一个XmlDocument,其根元素包含多个命名空间。我正在使用 C# 2.0 或 3.0

这是我的代码:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("JOBS", "http://www.example.com");
doc.AppendChild(root);

XmlElement job = doc.CreateElement("JOB", "http://www.example.com");
root.AppendChild(job);  

XmlElement docInputs = doc.CreateElement("JOB", "DOCINPUTS", "http://www.example.com");
job.AppendChild(docInputs);  

XmlElement docInput = doc.CreateElement("JOB", "DOCINPUT", "http://www.example.com");
docInputs.AppendChild(docInput);  

XmlElement docOutput = doc.CreateElement("JOB", "DOCOUTPUT", "http://www.example.com");
docOutputs.AppendChild(docOutput);  

当前输出:

<JOBS xmlns="http://www.example.com">
  <JOB>
    <JOB:DOCINPUTS xmlns:JOB="http://www.example.com">
      <JOB:DOCINPUT />
    </JOB:DOCINPUTS>
    <JOB:DOCOUTPUTS xmlns:JOB="http://www.example.com">
      <JOB:DOCOUTPUT />
    </JOB:DOCOUTPUTS>
  </JOB>
</JOBS>

但是,我想要的输出是:

<JOBS xmlns:JOBS="http://www.example.com" xmlns:JOB="http://www.example.com">
  <JOB>
    <JOB:DOCINPUTS>
      <JOB:DOCINPUT />
    </JOB:DOCINPUTS>
  <JOB:DOCOUTPUTS>
    <JOB:DOCOUTPUT />
  </JOB:DOCOUTPUTS>
  </JOB>
</JOBS>

我的问题:如何创建一个包含具有多个命名空间的根元素的XmlDocument

【问题讨论】:

  • 根据您的代码,您的意图似乎是让 具有默认命名空间“example.com”,但您描述的所需输出表明 不是命名空间。你能澄清一下吗?
  • @Oppositional - 继承命名空间;如果没有明确的命名空间,所有子元素都将从父元素继承。在这种情况下,格式由应用 AdLib 指定,它期望我发布的所需输出。

标签: c# .net xml namespaces xmldocument


【解决方案1】:

以下将生成您在上面请求的所需输出:

XmlDocument doc = new XmlDocument();

XmlElement root = doc.CreateElement("JOBS");
root.SetAttribute("xmlns:JOBS", "http://www.example.com");
root.SetAttribute("xmlns:JOB", "http://www.example.com");
doc.AppendChild(root);

XmlElement job = doc.CreateElement("JOB");

XmlElement docInputs    = doc.CreateElement("JOB", "DOCINPUTS", "http://www.example.com");
XmlElement docInput     = doc.CreateElement("JOB", "DOCINPUT", "http://www.example.com");
docInputs.AppendChild(docInput);
job.AppendChild(docInputs);

XmlElement docOutputs   = doc.CreateElement("JOB", "DOCOUTPUTS", "http://www.example.com");
XmlElement docOutput    = doc.CreateElement("JOB", "DOCOUTPUT", "http://www.example.com");
docOutputs.AppendChild(docOutput);
job.AppendChild(docOutputs);

doc.DocumentElement.AppendChild(job);

但是,在您的示例/所需输出中,对两个不同的前缀使用相同的 XML 命名空间似乎很奇怪。希望这会有所帮助。

【讨论】:

  • @Oppositional - 我同意奇怪的是,父 (JOBS) 和子 (JOB) 元素都明确声明相同的命名空间,而仅使用命名空间声明父元素就足够了。
  • 应该足够了。但是,当您与像 IRS 这样没有正确执行命名空间继承的顽固组织进行交互时,情况就不一样了。
【解决方案2】:

您可以在元素上显式创建命名空间前缀属性。然后,当您添加使用相同命名空间和相同前缀创建的后代元素时,XmlDocument 会发现它不需要向元素添加命名空间声明。

运行这个例子来看看它是如何工作的:

    using System;
    using System.Xml;

    static void Main(string[] args)
    {
        XmlDocument d = new XmlDocument();
        XmlElement e = d.CreateElement("elm");

        d.AppendChild(e);

        d.DocumentElement.SetAttribute("xmlns:a", "my_namespace");

        e = d.CreateElement("a", "bar", "my_namespace");
        d.DocumentElement.AppendChild(e);
        e = d.CreateElement("a", "baz", "other_namespace");
        d.DocumentElement.AppendChild(e);
        e = d.CreateElement("b", "bar", "my_namespace");
        d.DocumentElement.AppendChild(e);

        d.Save(Console.Out);

        Console.ReadLine();
    }

【讨论】:

  • @Robert - 感谢您的解释;它确实阐明了使用 SetAttribute 方法显式创建命名空间的能力。
【解决方案3】:

尝试将命名空间属性添加到根元素:

        XmlDocument doc = new XmlDocument();

        XmlElement root = doc.CreateElement("JOBS", "http://www.example.com");
        root.SetAttribute("xmlns:JOB", "http://www.example.com"); 

        doc.AppendChild(root);

        XmlElement job = doc.CreateElement("JOB", "http://www.example.com");
        root.AppendChild(job);

        XmlElement docInputs = doc.CreateElement("JOB", "DOCINPUTS", "http://www.example.com");
        job.AppendChild(docInputs);

        XmlElement docInput = doc.CreateElement("JOB", "DOCINPUT", "http://www.example.com");
        docInputs.AppendChild(docInput);

        XmlElement docOutput = doc.CreateElement("JOB", "DOCOUTPUT", "http://www.example.com");
        root.AppendChild(docOutput);    

【讨论】:

  • @divo - 嗯...我想知道使用 SetAttribute 在根元素中创建 2 个属性来代替显式声明命名空间是否有任何缺点?
猜你喜欢
  • 2019-03-23
  • 2012-08-16
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
  • 2014-01-06
  • 2011-02-10
  • 2011-10-22
  • 1970-01-01
相关资源
最近更新 更多