【问题标题】:Why does XElement fall over when parsing an xml file with an xmlns?为什么在使用 xmlns 解析 xml 文件时 XElement 会崩溃?
【发布时间】:2010-03-11 14:27:18
【问题描述】:

所以我正在尝试解析一个 xml 文件:

 <?xml version="1.0" encoding="utf-8" ?>
<Root>    
  <att1 name="bob" age="unspecified" xmlns="http://foo.co.uk/nan">    
  </att1>    
</Root>

使用以下代码:

XElement xDoc= XElement.Load(filename);
var query = from c in xDoc.Descendants("att1").Attributes() select c;
foreach (XAttribute a in query)
{
    Console.WriteLine("{0}, {1}",a.Name,a.Value);
}

除非我从 xml 文件中删除 xmlns="http://foo.co.uk/nan" ,否则不会向控制台写入任何内容,之后,我会得到预期的属性名称和值列表,并且根据我的需要!

编辑:格式化。

【问题讨论】:

标签: c# parsing linq-to-xml xml-namespaces xelement


【解决方案1】:

您必须在代码中使用相同的命名空间:

XElement xDoc= XElement.Load(filename);
XNamespace ns = "http://foo.co.uk/nan";
var query = from c in xDoc.Descendants(ns + "att1").Attributes() select c;
foreach (XAttribute a in query)
{
    Console.WriteLine("{0}, {1}",a.Name,a.Value);
}

属性不会选择默认的 (xmlns=....) 命名空间,因此您不需要限定它们。命名空间标签 (xmln:tags=....) 对文档或 API 使用来说是纯本地的,名称实际上是命名空间 + 本地名称,因此您必须始终指定命名空间。

【讨论】:

  • 这非常成功,谢谢。由于xml文件之间的命名空间很可能会发生变化,我猜你必须将文件作为字符串加载,然后查找命名空间并在代码中声明它?
  • @zotty 如果您查询 LocalName,则不需要字符串解析,如我的回答所示。
  • @zotty:如果命名空间不同,你的代码会更冗长,而且确实缺少命名空间的意义(节点的名称是命名空间+本地名称),但有时这是必要的。
【解决方案2】:

您对Descendants 的调用是在无命名空间中查询名为“att1”的元素。

如果您调用Descendants("{http://foo.co.uk/nan}att1"),您将选择命名空间元素,而不是非命名空间元素。

您可以像这样在任何名称空间或没有名称空间中选择名为“att1”的元素:

var query = from c in xDoc.Descendants() where c.Name.LocalName == "att1" select c.Attributes;

【讨论】:

    【解决方案3】:

    您需要在Descendants 调用中指定命名空间,如下所示:

    XNamespace ns = "http://foo.co.uk/nan";
    foreach (XAttribute a in xDoc.Descendants(ns + "att1"))
    {
        Console.WriteLine("{0}, {1}",a.Name,a.Value);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      相关资源
      最近更新 更多