我正在阅读一堆XML文件,转换它们并将数据加载到另一个系统.
以前我使用ThreadPool完成了这个,但是文件的提供者因此结构发生了变化,所以我现在正在尝试Aysync-Await并获得奇怪的结果.
当我处理文件时,我得到了一个xmlNodes列表并循环遍历它们
foreach (XmlNode currentVenue in venueNodes)
{
Console.WriteLine(currentVenue.OuterXml);
Console.WriteLine(currentVenue.SelectSingleNode(@"//venueName").InnerText);
}
Run Code Online (Sandbox Code Playgroud)
但是第二个WriteLine总是返回第一个节点的预期结果,例如:
<venue venueID="xartrix" lastModified="2012-08-20 10:49:30"><venueName>Artrix</venueName></venue>
Artrix
<venue venueID="xbarins" lastModified="2013-04-29 11:39:07"><venueName>The Barber Institute Of Fine Arts, University Of Birmingham</venueName></venue>
Artrix
<venue venueID="xbirmus" lastModified="2012-11-13 16:41:13"><venueName>Birmingham Museum & Art Gallery</venueName></venue>
Artrix
Run Code Online (Sandbox Code Playgroud)
这是完整的代码:
public async Task ProcessFiles()
{
string[] filesToProcess = Directory.GetFiles(_filePath);
List<Task> tasks = new List<Task>();
foreach (string currentFile in filesToProcess)
{
tasks.Add(Task.Run(()=>processFile(currentFile)));
}
await Task.WhenAll(tasks);
}
private async Task processFile(string currentFile)
{
try
{
XmlDocument currentXmlFile = new XmlDocument();
currentXmlFile.Load(currentFile);
//select nodes for processing
XmlNodeList venueNodes = currentXmlFile.SelectNodes(@"//venue");
foreach (XmlNode currentVenue in venueNodes)
{
Console.WriteLine(currentVenue.InnerXml);
Console.WriteLine(currentVenue.SelectSingleNode(@"//venueName").InnerText);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
显然我错过了什么,但我看不清楚,有人能指出来吗?
SelectSingleNode从文档中仅按文档顺序返回单个节点.@jbl是正确的,//venueName从文档根目录开始.该//XPath的运营商是"子选择"操作符.
我经常使用XML和XPath,这是一个常见的错误.调用时需要确保上下文节点正确SelectSingleNode.因此,就像我们所说的那样,使用从文档的根开始按文档顺序//venueName获取第一个<venueName />节点.
为了获得<venueName />您正在迭代的当前节点的子节点,您需要使用以下代码:
foreach (XmlNode currentVenue in venueNodes)
{
Console.WriteLine(currentVenue.OuterXml);
Console.WriteLine(currentVenue.SelectSingleNode(@".//venueName").InnerText); // The '.' means from the current node. Without it, searching starts from the document root, not currentVenue.
}
Run Code Online (Sandbox Code Playgroud)
那应该可以解决你的问题.