我必须生成如下所示的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
生成此文档?
答案 0 :(得分:1)
您可以执行以下操作:
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);
注意:
在命名空间中创建XmlElement
和XmlAttribute
节点时,始终喜欢使用带有前缀,localName和namespaceURI的Create()
重载:
XmlDocument.CreateElement(String, String, String)
XmlDocument.CreateAttribute(String, String, String)
从语义的角度来看,真正重要的是节点本地名称和名称空间;前缀只是在范围内查找命名空间声明的查找。
注意我没有显式添加xmlns:foo="http://www.example.com/xmlns/foo-version1"
属性?无需这样做,因为根元素是使用必需的名称空间和前缀通过doc.CreateElement("foo", "document", fooNs)
创建的。框架(XmlWriter
)在将xmlns:foo
写入XML时会自动发出XmlDocument
属性。
如果出于某种原因需要显式创建名称空间属性,则可以按以下步骤进行操作:
// 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 here。
顺便说一句,正如评论中所写,使用LINQ to XML可以更容易地做到这一点:
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)));
注意:
使用LINQ to XML,您从不不必担心XElement
或XAttribute
的名称空间前缀。只需使用XName
封装的正确名称空间和本地名称创建它们。框架(XmlWriter
)在编写时将自动发出所有必需的名称空间属性。
但是,如果由于某些原因确实需要配置名称空间,则可以构造适当的XAttribute
对象,然后将它们传递到XElement
constructor中。
有关更多信息,请参见 How to: Create a Document with Namespaces (C#) (LINQ to XML) 。
演示小提琴#2 here。
答案 1 :(得分:0)
Net库希望默认名称空间(不带前缀)为最后一个名称空间。我通常只使用具有较少限制的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);
}
}
}