Linq-to-XML获取具有名称空间的元素

问题描述:

我正在使用linq-to-xml来搜索元素。Linq-to-XML获取具有名称空间的元素

var doc = XDocument.Load(reader); 
        var ns = doc.Root.Attribute("xmlns").Value; 
        var result = (from u in doc.Descendants(XName.Get("MyElement", ns)) 

我需要摆脱使用XName.Get,每当我尝试在xml中找到一个元素。我如何设置一个默认的命名空间XDocument,以便它不会打扰搜索时。

问候。

这里是忽略默认命名的一种方式,如果你真的想这样做:

 XDocument doc; 
     using (XmlTextReader xr = new XmlTextReader("input.xml")) 
     { 
      xr.Namespaces = false; 
      doc = XDocument.Load(xr); 
     } 
     foreach (XElement bar in doc.Descendants("bar")) 

但我会建议接受命名空间的XML的存在和重要性,以及使用的XName和的XNamespace对象LINQ到XML提供与他们一起工作。

+0

是的,我同意命名空间的重要性,但在我的情况下,我的xml文档元素属于我已知的单个命名空间。所以我真的不需要在搜索元素时一次又一次地传递它。 – 2012-04-24 19:25:43

不能这样做:

doc = XDocument.Load(reader); 
var ns = doc.Root.Attribute("xmlns").Value; 
var result = from u in doc.Descendants.Elements(ns+"MyElement").Select(c=>c.Value); 
+0

再次,这将需要ns被连接,并使代码有点模糊。我们不能避免ns? – 2012-04-24 13:03:29

我需要摆脱使用XName.Get的,每当我试图找到在XML元素。我如何设置一个默认的命名空间XDocument,以便它不会打扰搜索时。

你不能 - 但也有其他两个选项:

  • 使用+(XNamespace, string)操作:

    doc.Descendants(ns + "MyElement") 
    
  • 刚刚创建XName值一次,然后引用它们你的查询,例如

    XName myElementName = ns + "MyElement"; 
    ... 
    doc.Descendants(myElementName); 
    

理想情况下,你不会动态创建的命名空间呢 - 难道你不知道应该寻找在命名空间?如果这样做,可以使用适当的XName值创建私有静态只读字段。

+0

所以没有办法说这个节点中的所有元素都属于这个命名空间,这将允许我通过名称正确地搜索元素? – 2012-04-24 13:08:44

+0

@Shoaib谢赫:你只能用'XName'搜索,而不能用字符串搜索。当您通过从字符串转换来创建'XName'时,会创建一个没有名称空间的'XName'。 – 2012-04-24 13:10:38

+0

在将它作为XDocument使用之前,您可以从xml的文本中删除命名空间。 – 2012-04-24 13:12:16

您也可以使用LocalName,它使LINQ错误化,但完成工作。 (在这种情况下从MSBuild项目文件获取属性)。

var imports = from i in doc.Root.Elements() 
       where i.Name.LocalName == "Import" 
       from p in i.Attributes() 
       where p.Name.LocalName == "Project" 
       select p.Value; 

我喜欢做这样的事情是,它留下的原始形式的XML,但它意味着给别人的东西有趣的是怎么回事。将“LocalName”放在LINQ表达式中就是一种自我记录的黑客行为。

如果代码分离,关闭XmlTextReader中的名称空间很容易被忽略。