C# 将LINQXML与命名空间一起使用

C# 将LINQXML与命名空间一起使用,c#,xml,linq,C#,Xml,Linq,我试图在XML文档中找到如下节点: <?xml version="1.0"?> <TrainingCenterDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"> <A

我试图在XML文档中找到如下节点:

<?xml version="1.0"?>
<TrainingCenterDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
  <Activities>
    <Activity Sport="CyclingTransport">
      <Id>2014-07-08T15:28:14Z</Id>
    </Activity>
  </Activities>
</TrainingCenterDatabase>
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants("Id")
                          .Select(x => (string)x)
                          .ToList();
Console.WriteLine(urlList.Count);
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants(System.Xml.Linq.XName.Get("Id", "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"))
                          .Select(x => (string)x)
                          .ToList();
Console.WriteLine(urlList.Count);
然后,结果是预期的计数1


因此,我的问题是如何考虑名称空间,以便在
TrainingCenterDatabase
节点具有这些属性时获得值?

XML中的名称空间可能很棘手。我自己也曾多次遇到过这个问题。很有可能,以下各项将解决您的问题:

XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants(doc.Root.Name.Namespace.GetName("Id"))
                          .Select(x => (string)x)
                          .ToList();
Console.WriteLine(urlList.Count);
XDocument doc=XDocument.Load(文件路径);
List urlist=doc.Root.subjections(doc.Root.Name.Namespace.GetName(“Id”))
.选择(x=>(字符串)x)
.ToList();
Console.WriteLine(urlist.Count);
基本上,这只是假设底层元素与根元素具有相同的名称空间。在这种情况下确实如此,但当然不必如此

正确的方法可能是明确地这样做。当然,这取决于你如何使用这个和你的数据源,所以你自己做决定,但这需要做更多类似的事情:

<?xml version="1.0"?>
<TrainingCenterDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
  <Activities>
    <Activity Sport="CyclingTransport">
      <Id>2014-07-08T15:28:14Z</Id>
    </Activity>
  </Activities>
</TrainingCenterDatabase>
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants("Id")
                          .Select(x => (string)x)
                          .ToList();
Console.WriteLine(urlList.Count);
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants(System.Xml.Linq.XName.Get("Id", "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"))
                          .Select(x => (string)x)
                          .ToList();
Console.WriteLine(urlList.Count);
XDocument doc=XDocument.Load(文件路径);
List urlList=doc.Root.subjects(System.Xml.Linq.XName.Get(“Id”),”http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"))
.选择(x=>(字符串)x)
.ToList();
Console.WriteLine(urlist.Count);
问题的原因是,
XElement
的默认行为是,当没有给出显式名称空间时,不使用名称空间。但是,XML规范的默认行为是假定父名称空间。在您的例子中,这两个是不同的,因此它无法找到后代。

它可以工作

        XDocument doc = XDocument.Load(filePath);
        XNamespace ns = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2";
        var root = doc.Descendants(ns + "Id").Select(x => x.Value).ToList();
        Console.WriteLine(root.Count);

这很有效。因此,在原始示例中,列表的计数为0的原因是因为假定元素与根元素的名称空间不同?@DanSmith很好,我没有真正解释错误所在。我编辑了我的答案。但是是的,基本上它是在寻找一个没有名称空间的元素和一个名为“Id”的
Name
,它与您正在寻找的有名称空间的元素不匹配。另一种方法是使用LocalName,而忽略名称空间: