簡體   English   中英

即使節點發生更改,xmlNode.SelectSingleNode也始終返回相同的值

[英]xmlNode.SelectSingleNode always returns same value even though the node changes

我正在閱讀一堆XML文件,轉換它們並將數據加載到另一個系統。

以前我使用ThreadPool完成了這個,但是文件的提供者因此結構發生了變化,所以我現在正在嘗試Aysync-Await並獲得奇怪的結果。

當我處理文件時,我得到了一個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

這是完整的代碼:

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);
     }
 }

顯然我錯過了什么,但我看不清楚,有人能指出來嗎?

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.
}

那應該可以解決你的問題。

不是//venueName從文檔根目錄搜索?

我想,結合SelectSingleNode ,總是會在同一結果節點(文檔的第一個venueName節點)上結束

您可以嘗試使用venueName替換//venueName venueName

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM