5

我正在使用 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,以便在搜索时不会打扰。

问候。

4

6 回答 6

7

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

        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 对象来处理它们。

于 2012-04-24T13:24:41.897 回答
4

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

你不能 - 但还有其他两种选择:

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

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

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

理想情况下,无论如何您都不会动态创建名称空间——您不知道您应该查看的名称空间吗?如果这样做,您可以创建具有适当XName值的私有静态只读字段。

于 2012-04-24T13:06:11.457 回答
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);
于 2012-04-24T13:02:14.267 回答
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 中关闭命名空间很容易被忽略。

于 2015-10-26T19:37:45.660 回答
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")).
  • 之后(只要后代元素具有相同的命名空间)使用上述扩展方法。
于 2019-01-14T11:11:18.353 回答
0

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

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

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

            if (doc.Root != null)
                foreach (XElement xElement in doc.Root.Elements())
                {
                    Console.WriteLine(xElement);
                }
于 2021-05-08T11:21:24.557 回答