我试图在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>
我的目标是使用以下代码提取节点值'Id':
XDocument doc = XDocument.Load(filePath);
List<string> urlList = doc.Root.Descendants("Id")
.Select(x => (string)x)
.ToList();
Console.WriteLine(urlList.Count);
然而,计数是0,我期望1.
在对XML进行一些调试和编辑之后,我注意到如果我更改了TrainingCenterDatabase
节点并删除了属性:
<TrainingCenterDatabase>
然后结果是按预期计数1。
所以我的问题是如何考虑命名空间,以便在TrainingCenterDatabase
节点具有这些属性时获取值?
答案 0 :(得分:3)
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(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);
问题的原因是XElement
的默认行为,如果没有给出明确的命名空间,则假设 no 名称空间。但是,XML规范的默认行为是假定父命名空间。在你的情况下,这两个是不同的,所以它无法找到后代。
答案 1 :(得分:0)
有效......
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);