C# xmlNode.SelectSingleNode始终返回相同的值,即使节点发生更改

C# xmlNode.SelectSingleNode始终返回相同的值,即使节点发生更改,c#,xml,C#,Xml,我正在读取一堆XML文件,转换它们并将数据加载到另一个系统中 以前我使用ThreadPool完成了这项工作,但是文件的提供者和结构都发生了变化,所以我现在尝试Aysync Wait并得到一个奇怪的结果 在处理这些文件时,我会得到一个xmlNodes列表,并在其上循环 foreach (XmlNode currentVenue in venueNodes) { Console.WriteLine(currentVenue.OuterXml); Console.WriteLi

我正在读取一堆XML文件,转换它们并将数据加载到另一个系统中

以前我使用ThreadPool完成了这项工作,但是文件的提供者和结构都发生了变化,所以我现在尝试Aysync Wait并得到一个奇怪的结果

在处理这些文件时,我会得到一个xmlNodes列表,并在其上循环

foreach (XmlNode currentVenue in venueNodes)
{
      Console.WriteLine(currentVenue.OuterXml);
      Console.WriteLine(currentVenue.SelectSingleNode(@"//venueName").InnerText);
}
但是,第二条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 &amp; Art Gallery</venueName></venue>
Artrix
Artrix
阿特里克斯
伯明翰大学理发学院美术学院
阿特里克斯
伯明翰博物馆;美术馆
阿特里克斯
以下是完整的代码:

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);
     }
 }
public异步任务ProcessFiles()
{
字符串[]filesToProcess=Directory.GetFiles(\u filePath);
列表任务=新列表();
foreach(filesToProcess中的字符串currentFile)
{
tasks.Add(Task.Run(()=>processFile(currentFile));
}
等待任务。何时(任务);
}
专用异步任务进程文件(字符串currentFile)
{
尝试
{
XmlDocument currentXmlFile=新的XmlDocument();
currentXmlFile.Load(currentFile);
//选择要处理的节点
XmlNodeList venueNodes=currentXmlFile.SelectNodes(@”//venue);
foreach(VenuNodes中的XmlNode currentVenue)
{
Console.WriteLine(currentVincement.InnerXml);
Console.WriteLine(CurrentVince.SelectSingleNode(@”//VenuName”).InnerText);
}
}
捕获(例外e)
{
控制台写入线(e.Message);
}
}

显然我遗漏了一些东西,但我看不到什么,有人能指出吗?

没有从文档根目录中搜索VenuName

我猜,与
SelectSingleNode
相结合,将始终在相同的结果节点(文档的第一个
venueName
节点)上结束


您可以尝试将
//venueName
替换为
venueName

选择SingleNode
仅从文档中按文档顺序返回单个节点@jbl是正确的,
//venueName
从文档根开始。xpath运算符是“后代选择器”运算符

我经常使用XML和XPath,这是一个常见的错误。调用
SelectSingleNode
时,需要确保上下文节点正确。所以,正如我们刚才所说的,使用
//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.
}

这应该可以解决您的问题。

yes//从文档的根目录进行搜索,但是在本例中,文档只是一个已被删除的节点extracted@Stuart它不是那样工作的。您拥有的
XmlNode
仍然链接到整个文档,您没有“提取”它或类似的内容。没有理由使
processFile()
异步。你应该得到一个警告。另外,并行处理文件可能不会给您带来任何性能改进。谢谢各位,我将接受这个答案,因为它更详细,希望将来能帮助其他人。我认为在节点父文档上下文中执行节点对象上的方法是不直观的。它类似于字符串[1]。包含(“apple”)搜索整个数组,而不是索引1处的字符串。奇怪。我同意你的说法,这是
SelectSingleNode
的意外行为。和您一样,我最初认为该方法足够聪明,可以将上下文节点设置为调用该方法的节点。一点也不直观。为了避免怀疑,也许这和Xpath规范有关。。。。