手动迭代选定的XML元素(C#,XDocument)
对XDocument中的一组元素进行手动迭代的“最佳实践”方法是什么(即,一次迭代一个,并按“下一步”按钮)?假设我选择了我想要的元素集:手动迭代选定的XML元素(C#,XDocument),c#,.net,xml,iterator,linq-to-xml,C#,.net,Xml,Iterator,Linq To Xml,对XDocument中的一组元素进行手动迭代的“最佳实践”方法是什么(即,一次迭代一个,并按“下一步”按钮)?假设我选择了我想要的元素集: var elems = from XElement el in m_xDoc.Descendants() where (el.Name.LocalName.ToString() == "q_a") select el; 我可以使用IEnumerator对它们进行迭代,即。, IEnumerator m_it
var elems = from XElement el in m_xDoc.Descendants()
where (el.Name.LocalName.ToString() == "q_a")
select el;
我可以使用IEnumerator对它们进行迭代,即。,
IEnumerator m_iter
但是当我到了结尾,如果我调用Reset(),我想回到开头,它会抛出一个NotSupportedException。这是因为,正如第22章“迭代器”中的Microsoft C#2.0规范所说,“请注意,枚举器对象不支持IEnumerator.Reset方法。调用此方法会引发System.NotSupportedException。”
那么,正确的做法是什么呢?如果我还想进行双向迭代,也就是“后退”按钮,该怎么办
微软论坛上有人说我无论如何都不应该直接使用IEnumerable。他说有一种方法可以让林克做我想做的事,但我不明白是什么。其他人建议使用ToList()将Xelement转储到列表中,我认为这会起作用,但我不确定这是“最佳实践”。提前感谢您的建议 解决方案非常简单。只需从XElements集合中创建一个列表
var elems = (from XElement el in m_xDoc.Descendants()
where (el.Name.LocalName.ToString() == "q_a")
select el).ToList();
您可以通过索引器elems[i]
进行枚举,并来回跳转。只需将当前索引存储在一个变量中,然后单击按钮(使用环绕)即可减少/增加它
linq查询会根据需要解析您拥有的xml(有关详细信息,请参阅MSDN)。即使它支持IEnumerable.Reset()
,每次都必须再次解析它。如果调用.ToList()
它会一次性解析所有子元素并将它们加载到内存中。很少需要直接使用枚举器;只需在elems
上使用foreach
。这里重复两次:
// first time
foreach(var item in elems) {...}
// second time
foreach(var item in elems) {...}
无需使用
Reset()
-它只需为您使用GetEnumerator()
两次,这是正确的方法。如果出于任何原因无法运行查询两次,或者希望随机访问而不是顺序访问,那么您必须将其缓冲-可能会将其放入带有ToList()
的列表中,我认为foreach
循环不是op要搜索的。他只想在用户按下按钮时获取下一个元素。我认为他最好把数据存储到一个列表中。