我试图创建一个程序来读取包含多个具有相同名称的元素的xml文件。我想阅读这些元素并将它们放入检查表框中。
该文件如下所示:
<Item>Something</Item>
<Item>Something</Item>
<Item>Something</Item>
等等。 我已经尝试过的是:
private void Form2_Load(object sender, EventArgs e) {
var doc = XDocument.Load(@ "C:\\Hello.xml");
var history = doc.Root
.Elements("Item")
.Select(x => x.Value);
foreach(var x in history) {
checkedListBox1.Items.Add(x);
}
}
有人可以帮我这个吗?
答案 0 :(得分:0)
您必须确保您的XML文档具有单个根元素。试试这个:
<Items>
<Item>Something</Item>
<Item>Something</Item>
<Item>Something</Item>
</Items>
然后阅读其子元素。
答案 1 :(得分:0)
首先,XDocument
并不像您猜测的那样有效。它的工作方式是它被记录为工作的方式。您会发现这种行为在许多不同的编程接口中令人沮丧地保持一致。
但即使没有阅读文档(也没有人喜欢阅读文档),您可以通过设置断点并将鼠标悬停在您看到的所有内容上来学习很多东西。
所以这里是如何运作的。
此表达式返回XML文档的根元素,在您实际解析的一个案例中为Item
。它只返回一个单独的元素,而不是一个集合。
var x = doc.Root;
这将返回XML文档的根元素的所有子:
var history = doc.Root.Elements();
这将返回根元素的 children 的部分 - 只是名为&#34; Foo&#34;
的var history = doc.Root.Elements("Foo");
这里再次提供整个XML文件:
<Item>Something</Item>
Item
是根元素,它没有子元素。 Root.Elements()
永远不会在该文件上返回任何内容,因为根元素没有子元素。 Item
只有一个值。现在,我们可以获得这个价值:
var x = doc.Root.Value;
checkedListBox1.Items.Add(x);
您必须注意到history
不包含任何内容。现在你知道为什么了。
该案例的下一步是返回并找出Root
是什么。从头开始。你知道doc
是什么。将鼠标悬停在工具提示中显示XML。你知道它解析了正确的文件,你知道当你在上调用Elements()
时,任意命名的Root
返回完全未知的东西时,什么都没有出来。
那么Root
是什么?将鼠标悬停在它上面。为什么Root.Elements()
什么都没有返回?它显然不会做你认为它做的事情,因为你期望发生的事情不会发生。如果你完全没有猜测,请谷歌吧。
当您尝试在XML中放置多个Item
元素时,接下来要查找的是XML解析错误。如果一个人没有工作,你可能不会得到更好的结果与几个,但我想这是值得一试。
正如错误消息告诉您的那样,XML文档只能有一个根元素。如果您之前看过XML,那么您已经注意到它的层次结构:元素可以包含多个子元素,依此类推(无限期)(&#34;拉丁语为&#34; out堆栈空间&#34;)。
以下是如何将多个元素放入XML文件中:
<Items>
<Item>Foo</Item>
<Item>Bar</Item>
<Item>Baz</Item>
<Item>Planxty</Item>
</Items>
现在doc.Root
是Items
元素,它有子元素。这使得Elements()
可以使用。我们将在LINQ表达式的末尾添加ToList()
,这样当我们将鼠标悬停在它上面时,调试器会向我们显示集合的计数:
var history = doc.Root
.Elements("Item")
.Select(x => x.Value)
.ToList();
doc.Root.Elements("Item")
查找名为&#34; Item&#34;的Root
的所有子项,并枚举它们。 doc.Root
元素的命名并不重要。在解析器接受的任何文件中只有一个doc.Root
,所以它不会像你得到错误的那样。如果您想在Root
名称错误时让用户烦恼,那就是一个单独的操作:
if (doc.Root.Name != "Items")
{
MessageBox.Show("Just click OK, nobody reads error messages.");
}