Linq-to-XML获取带命名空间的元素

时间:2012-04-24 12:56:54

标签: .net 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))

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

问候。

6 个答案:

答案 0 :(得分:5)

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

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

但我建议接受XML中命名空间的存在和重要性,并使用LINQ to XML提供的XName和XNamespace对象来处理它们。

答案 1 :(得分:4)

  

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

你不能 - 但还有两个选择:

  • 使用+(XNamespace, string)运算符:

    doc.Descendants(ns + "MyElement")
    
  • 只需创建一次XName值,然后在查询中引用它们,例如

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

理想情况下,您无论如何都不会动态创建命名空间 - 您是否知道您应该查找的命名空间?如果这样做,您可以使用适当的XName值创建私有静态只读字段。

答案 2 :(得分:1)

你不能这样做:

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);

答案 3 :(得分:1)

你也可以使用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中的命名空间。

答案 4 :(得分:0)

创建扩展方法:

        public static XElement ElementInCurrentNamespace(this XElement element, string elementName)
        {
            return element
                .Element(element.Name.Namespace.GetName(elementName));
        }

        public static IEnumerable<XElement> ElementsInCurrentNamespace(this XElement element, string elementName)
        {
            return element
                .Elements(element.Name.Namespace.GetName(elementName));
        }
  • 首次访问带有名称空间的元素时,请使用带有名称空间的.Element.Elements方法,例如element.Element(namespace.GetName("foo"))
  • 之后(只要后代元素具有相同的名称空间),请使用上述扩展方法。

答案 5 :(得分:0)

这是一篇旧帖子,但这是我的想法:

Elements.xml 根元素包含一个命名空间属性。以下代码忽略命名空间。

XDocument doc = XDocument.Load("Elements.xml");

            if (doc.Root != null)
                foreach (XElement xElement in doc.Root.Elements())
                {
                    Console.WriteLine(xElement);
                }