XElement命名空间(如何?)


73

如何使用节点前缀创建xml文档,例如:

<sphinx:docset>
  <sphinx:schema>
    <sphinx:field name="subject"/>
    <sphinx:field name="content"/>
    <sphinx:attr name="published" type="timestamp"/>
 </sphinx:schema>

当我尝试运行类似new XElement("sphinx:docset")异常的东西时

未处理的异常:System.Xml.XmlException:名称中不能包含':'字符,十六进制值0x3A。
在System.Xml.XmlConvert.VerifyNCName(字符串名称,ExceptionType exceptionTyp E)
在System.Xml.Linq.XName..ctor(NS的XNamespace,字符串的localName)
在System.Xml.Linq.XNamespace.GetName(字符串的localName)
在系统.Xml.Linq.XName.Get(字符串expandName)


看一XmlNamespaceManager堂课。
2011年

2
您的文件将无效。它需要声明sphinx前缀。
约翰·桑德斯

Answers:


118

在LINQ to XML中非常简单:

XNamespace ns = "sphinx";
XElement element = new XElement(ns + "docset");

或者使“别名”正常工作,使其看起来像您的示例,如下所示:

XNamespace ns = "http://url/for/sphinx";
XElement element = new XElement("container",
    new XAttribute(XNamespace.Xmlns + "sphinx", ns),
    new XElement(ns + "docset",
        new XElement(ns + "schema"),
            new XElement(ns + "field", new XAttribute("name", "subject")),
            new XElement(ns + "field", new XAttribute("name", "content")),
            new XElement(ns + "attr", 
                         new XAttribute("name", "published"),
                         new XAttribute("type", "timestamp"))));

产生:

<container xmlns:sphinx="http://url/for/sphinx">
  <sphinx:docset>
    <sphinx:schema />
    <sphinx:field name="subject" />
    <sphinx:field name="content" />
    <sphinx:attr name="published" type="timestamp" />
  </sphinx:docset>
</container>

1
谢谢,但是对于第一个版本,我得到了<docset xmlns =“ sphinx” />,这不是我想要的;))))
Edward83,2011年

@ Edward83:看看我的另一个例子。基本上,您需要在xmlns中的某个地方指定名称空间...
Jon Skeet

在经历了所有丑陋的骇客之后,我曾经这样做(将静态名称空间附加到所有内容的递归静态方法)...我首先尝试了这种方法,但是我没有在外部名称空间前面加上XNamespace.Xmlns前缀。为什么甚至需要该前缀?是否将其设置为全球性?
micahhoover

@micahhoover:您应该阅读W3C名称空间规范。对我来说,您要达到的目标或出错的原因尚不完全清楚。
乔恩·斯基特

22

您可以读取文档的名称空间,并在如下查询中使用它:

XDocument xml = XDocument.Load(address);
XNamespace ns = xml.Root.Name.Namespace;
foreach (XElement el in xml.Descendants(ns + "whateverYourElementNameIs"))
    //do stuff

1
不错的方法(+1)!但是,在根XML元素具有多个xmlns属性的情况下,这对我不起作用,即:xmlns:soapenv =“ ...” xmlns =“ ...”。使用xml.Root.GetDefaultNamespace()确实得到了我想要的,这就是纯xmlns =“ ...”属性的值。
乔恩·施耐德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.