我正在加载此KML:http://www.mcallen.net/Files/docs/traffic/bike/kml/McBikeRoutes.kml
进入XDocument,如果我查看调试器中的XDocument,它似乎正确填充了文件的内容。
但是,当我尝试访问任何后代时,无论我做什么,它都会变空。
var xDoc = XDocument.Load("Assets/McBikeRoutes.kml");
var d = xDoc.Descendants(); // <-- Empty result
在上面的代码中,McBikeRoutes.kml是上面链接的文件的精确副本,我只是手动将它添加到我的项目中,因此它在内部而不是在线获取。
另外,我可以验证xDoc DOES加载文件,就像我在调试器中观察它一样,我可以看到它包含完整的KML文档内容。
但是,无论我如何尝试访问后代,结果总是为空。
我尝试在文档中包含默认命名空间和所有其他命名空间,但无论我做什么都没有结果。
我终于尝试了xDoc.Descendants()来获取所有内容,而且这也是空的!
我尝试了xDoc.Root.Descendants()和xDoc.Document.Descendants(),以及xDoc.Elements(),xDoc.Root.Elements()和xDoc.Document.Elements()以及EVERTHING返回一个空结果,即使XDocument中有明显的信息。
奇怪的是,如果我这样做:
((XElement)xDoc.FirstNode)
我确实得到了第一个后代XElement!但如果我这样做:
((XElement)xDoc.FirstNode).Descendants()
我仍然没有得到任何结果(当我尝试Elements()时同样的事情)!
任何人都知道我在这里做错了什么?是因为该文件是KML吗?
答案 0 :(得分:0)
我现在将此转移到答案。
Descendants()有两种方法 http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.descendants.aspx
Public method Descendants()
Returns a collection of the descendant elements for this document or element,
in document order. (Inherited from XContainer.)
Public method Descendants(XName)
Returns a filtered collection of the descendant elements for this
document or element, in document order. Only elements that have a
matching XName are included in the collection. (Inherited from XContainer.)
如果用错误的参数调用Descendants(XName)
,很可能你没有后代。如果你使用Descendants()
[sic],我希望得到所有的后代。
FirstNode
给出非空答案的原因是您无法使用参数更改其行为,因此无法避免正确调用它。
请发布您的实际代码
更新。此讨论不是解决问题的最有效方法。您应该构建一个SSCCE(https://meta.stackexchange.com/questions/22754/sscce-how-to-provide-examples-for-programming-questions)“短,自包含,正确(可编译),示例。”
你应该做的是创建一个小例子。我将获取您的KML文件并创建可以读入的最小有效子集,以及您可以在哪里显式地显示您认为失败的方法。 (顺便说一句,我认为这个问题不太可能是KML-我认为这就是你如何调用方法和/或你所期望的)。我会尝试读取XML字符串,以便它可以在SO上发布并提供您正在使用的完整代码以及您实际获得的代码。诸如“空”之类的单词不够精确 - 它是否意味着IEnumeration具有零元素,如某些函数所报告的那样? (我对XDocument的了解已有几年了。)
如果您创建了SSCCE,我可以帮助您。 (我不知道)。但至少我们可以用精确的术语表达你的问题。
更新: 既然你没有发布任何代码,我会猜测是什么问题: 你的后代()和元素()实际上包含节点,但你没有正确地询问它们。 如果您发布了代码,我会花更少的时间给您答案。
UPDATE 感谢调试器快照。我猜这是问题最初表现出来的地方。首先,您必须使用精确的术语 - 您写了“空”但调试器将其标记为“null”。它们是完全不同的,使用一个会导致另一个误导。
我怀疑并且您是否无法使用调试器来显示后代元素。我认为你和你的调试器彼此不了解。这是不可能通过网络调试。
Descendants()是一个IEnumerable:
public IEnumerable<XElement> Descendants()
我的C#/ Linq生锈了,我没有工作系统,但总的来说,这意味着它提供了按顺序获取元素的方法。它唯一的方法是:
GetEnumerator()(http://msdn.microsoft.com/en-us/library/s793z9y2.aspx)
您将不得不弄清楚如何在CODE(而不是调试器)中获取后代,因此您需要学习如何遍历IEnumerable。从内存中可以看出:
foreach (XElement descendant : getDescendants()) {
printSomehowOrDoSomething(descendant);
}
如果您编写了想要使用的实际代码并运行它,那么它可以执行您想要的任务,也可以更清楚地了解您可以进行通信的问题。 (我不知道为什么你的调试器说“null” - 它可能在技术上是正确的但是误导性。你的screencap(+按钮)表明枚举有孩子。
简单地说:忘记调试器(它不是代码)和编写你想要执行的代码,就像在第一个实例中一样(不超过10行)。小片段(SSCCE)的价值在于它可以立即被其他人重现 - 它们可以在自己的系统中剪切和粘贴并运行。代码及其错误比调试器精确得多。顺便说一下,我希望您使用单元测试和测试驱动开发 - 如果您创建了一个失败的测试,那么问题就在哪里就可以了。