C# 可以用两个xml名称空间创建一个XmlElement吗?

C# 可以用两个xml名称空间创建一个XmlElement吗?,c#,xml,xmldocument,C#,Xml,Xmldocument,我必须生成如下所示的XML: <foo:document xmlns="http://www.example.com/xmlns" xmlns:foo="http://www.example.com/xmlns/foo-version1"> <foo:bar foo:baz="true" /> </foo:document> 如何使用c#中的System.Xml.XmlDocument生成此文档?网络库希望默认名称空间(不带前缀)成为最后一个名称

我必须生成如下所示的XML:

<foo:document xmlns="http://www.example.com/xmlns" xmlns:foo="http://www.example.com/xmlns/foo-version1">
    <foo:bar foo:baz="true" />
</foo:document>


如何使用c#中的
System.Xml.XmlDocument
生成此文档?

网络库希望默认名称空间(不带前缀)成为最后一个名称空间。我通常只使用限制较少的Parse方法。见下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = "<foo:document xmlns=\"http://www.example.com/xmlns\" xmlns:foo=\"http://www.example.com/xmlns/foo-version1\">" +
                         "   <foo:bar foo:baz=\"true\" />" +
                         "</foo:document>";

            XDocument doc = XDocument.Parse(xml);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串xml=“”+
"   " +
"";
XDocument doc=XDocument.Parse(xml);
}
}
}

您可以按如下方式执行此操作:

var fooNs = "http://www.example.com/xmlns/foo-version1";
var defNs = "http://www.example.com/xmlns";

var doc = new XmlDocument();

// Create and add the root element
var root = doc.CreateElement("foo", "document", fooNs);
doc.AppendChild(root);

// Add the default namespace (do note the root element is not in this namespace)
var defAttr = doc.CreateAttribute("xmlns");
defAttr.Value = defNs;
root.Attributes.Append(defAttr);

// Create the <foo:bar> element
var bar = doc.CreateElement("foo", "bar", fooNs);
var bazAttr = doc.CreateAttribute("foo", "baz", fooNs);
bazAttr.Value = XmlConvert.ToString(true);
bar.Attributes.Append(bazAttr);

// Add it to the root
root.AppendChild(bar);
// The following is redundant as the framework (XmlWriter) will add the necessary
// xmlns:foo attribute as the XmlDocument is being written.  If you need to do it anway 
// (e.g. to control the order) you can do it as follows.
// (But note that XML attributes are unordered according to the XML specification, for details
// see https://stackoverflow.com/questions/33746224/in-xml-is-the-attribute-order-important)
var xmlnsNs = "http://www.w3.org/2000/xmlns/";

var fooAttr = doc.CreateAttribute("xmlns", "foo", xmlnsNs);
fooAttr.Value = fooNs;
root.Attributes.Append(fooAttr);
演示小提琴#1

顺便说一句,正如在评论中所写的那样,使用以下工具更容易做到这一点:

注:

  • 使用LINQtoXML,您无需担心
    XElement
    XAttribute
    的名称空间前缀。只需使用正确的名称空间和本地名称创建它们,如所封装的。框架(
    XmlWriter
    )将在写入时自动发出所有必要的名称空间属性

    但是,如果出于某种原因确实需要配置名称空间,则可以构造适当的
    XAttribute
    对象,然后将它们传递到

  • 如需进一步阅读,请参阅


演示小提琴#2.

您需要
XmlDocument
而不是
XDocument
的任何特殊原因?LINQtoXML在名称空间支持方面比IMO干净得多。您看过和了吗?这些回答了你的问题吗?如果没有,那么到目前为止,您尝试过哪些不起作用的方法?@dbc:您尝试过创建节点吗?默认名称空间不是最后一个名称空间,Net library希望将默认名称空间视为最后一个属性。@jdweng-是的,我看到了。我能够通过
XmlDocument
XDocument
获得所需的输出。
XNamespace fooNs = "http://www.example.com/xmlns/foo-version1";
XNamespace defNs = "http://www.example.com/xmlns";

var root = new XElement(fooNs + "document"
                        // Add the namespace declarations with your desired prefixes.  Be sure to pass them into the constructor.
                        , new XAttribute("xmlns", defNs.ToString())
                        , new XAttribute(XNamespace.Xmlns + "foo", fooNs.ToString())
                        // And add any required content.  The content can be passed into the constructor, or added later. 
                        , new XElement(fooNs + "bar", new XAttribute(fooNs + "baz", true)));