2013-05-07 74 views
1

我有以下方法查詢XML文件。我需要它返回所有具有與我傳入我的方法的'sys'變量匹配的「System」元素的所有文件的信息。C#Linq到XML查詢只返回1結果

它工作正常,但只返回1個結果,當我知道XML文件中有多個匹配項時。

就好像我的Linq查詢只是執行XML文件,直到找到結果然後停止,而我需要它來獲取所有匹配的集合。

public ListViewItem getDMcollection(string sys) 
     { 

      XDocument doc = XDocument.Load(Form1.CSDBpath + Form1.projectName + "\\Data.xml"); 

      var dms = from dm in doc.Descendants("dataModule") 
         where dm.Descendants("system").First().Value == sys 
         select dm; 

      foreach (var module in dms) 
      { 
        ListViewItem item = new ListViewItem(new string[] 
       { 
         module.Element("DMC").Value, 
         module.Element("techName").Value, 
         module.Element("infoName").Value, 
         module.Element("status").Value, 
         module.Element("currentUser").Value, 
         module.Element("validator").Value, 
         module.Element("notes").Value, 
         //dm.Element("size").Value + " kb", 
         //dm.Element("dateMod").Value 
       }); 

        return item; 

       } 

       return null; 

     } 

這是XML文件的樣本:

<DMs> 
    <dataModule> 
    <DMC>DMC-AJ-A-29-13-54-00ZZZ-254Z-B_001-00.XML</DMC> 
    <techName>Pressure switch</techName> 
    <infoName>Clean mechanically</infoName> 
    <system>72</system> 
    <subsystem>13</subsystem> 
    <subsubsystem>60</subsubsystem> 
    <status>Checked Out</status> 
    <notes>-</notes> 
    <currentUser>JakeMemery</currentUser> 
    <validator>-</validator> 
    <dateMod>-</dateMod> 
    <size>-</size> 
    </dataModule> 
    <dataModule> 
    <DMC>DMC-AJ-A-30-15-62-00AAA-066A-D_001-00.XML</DMC> 
    <techName>Pressure switch</techName> 
    <infoName>Support equipment and tools data</infoName> 
    <system>29</system> 
    <subsystem>13</subsystem> 
    <subsubsystem>54</subsubsystem> 
    <status>Checked In</status> 
    <notes>-</notes> 
    <currentUser>-</currentUser> 
    <validator>-</validator> 
    <dateMod>-</dateMod> 
    <size>-</size> 
    </dataModule> 
    <dataModule> 
    <DMC>DMC-AJ-A-45-60-12-00AAA-420A-B_001-00.XML</DMC> 
    <techName>Pressure switch</techName> 
    <infoName>General fault isolation procedure</infoName> 
    <system>29</system> 
    <subsystem>20</subsystem> 
    <subsubsystem>10</subsubsystem> 
    <status>Checked In</status> 
    <notes>-</notes> 
    <currentUser>-</currentUser> 
    <validator>-</validator> 
    <dateMod>-</dateMod> 
    <size>-</size> 
    </dataModule> 
</DMs> 

因此,作爲一個例子,我可能會在經過29我的方法的價值。正如你可以看到上面的XML文件包含兩個'系統'29匹配,但我的程序只回退其中的1個 - 第一個。

調用以上並傳遞在「SYS」變量的方法是這樣的:

public ListViewItem splitSNS(string fullSNSpath) 
     { 
      string sns = new String(fullSNSpath.ToCharArray().Where(c => Char.IsDigit(c)).ToArray()); 

      if (sns.Length.ToString() == "6") 
      { 
       string sys = sns.Substring(4, 2); 
       string subsys = sns.Substring(2, 2); 
       string unit = sns.Substring(0, 2); 

       ListViewItem dms = getDMcollection(sys, subsys, unit); 
       return dms; 
      } 
      else if (sns.Length.ToString() == "4") 
      { 
       string sys = sns.Substring(2, 2); 
       string subsys = sns.Substring(0, 2); 

       ListViewItem dms = getDMcollection(sys, subsys); 
       return dms; 

      } 
      else if (sns.Length.ToString() == "2") 
      { 
       string sys = sns.Substring(0, 2); 

       ListViewItem dms = getDMcollection(sys); 
       return dms; 
      } 

      return null; 
     } 

並調用上述方法的提取物是

ListViewItem dms = newFilter.splitSNS(fullSNSpath); 

        if (dms != null) 
        { 

         // showfilteredList(dms); 
         listView1.Items.Add(dms); 

         showStatus(dms); 
        } 
        else 
        { 
         MessageBox.Show("There are no DMs to be displayed"); 
        } 
+0

這行可能是這個問題:where dm.Descendants(「system」)。First() .Value == sys,因爲您只需要First()項目。 – Ric 2013-05-07 08:08:12

回答

2

,我可以看到你的函數設計只有一個元素返回。您嘗試循環低谷查詢,但return item;語句將始終返回查詢中的第一個元素。也許你需要將其返回類型更改爲IEnumerable<ListViewItem>,並將return item;更換爲yield return item;例如?

對於你的情況,我建議爲getDMcollection功能如下變化:

public IEnumerable<ListViewItem> getDMcollection(string sys) 
{  
    XDocument doc = XDocument.Load(Form1.CSDBpath + Form1.projectName + "\\Data.xml"); 

    var dms = from dm in doc.Descendants("dataModule") 
       where dm.Descendants("system").First().Value == sys 
       select dm; 

    foreach (var module in dms) 
    { 
     ListViewItem item = new ListViewItem(new string[] 
     { 
      module.Element("DMC").Value, 
      module.Element("techName").Value, 
      module.Element("infoName").Value, 
      module.Element("status").Value, 
      module.Element("currentUser").Value, 
      module.Element("validator").Value, 
      module.Element("notes").Value, 
      //dm.Element("size").Value + " kb", 
      //dm.Element("dateMod").Value 
     }); 

     yield return item;  
    } 
} 

當你調用它,你應該重複它的結果將它們添加到列表框中

public IEnumerable<ListViewItem> splitSNS(string fullSNSpath) 
    { 
     string sns = new String(fullSNSpath.ToCharArray().Where(c => Char.IsDigit(c)).ToArray()); 

     if (sns.Length.ToString() == "6") 
     { 
      string sys = sns.Substring(4, 2); 
      string subsys = sns.Substring(2, 2); 
      string unit = sns.Substring(0, 2); 

      IEnumerable<ListViewItem> dms = getDMcollection(sys, subsys, unit); 
      foreach(var d in dms) 
       yield return d; 
     } 
     else if (sns.Length.ToString() == "4") 
     { 
      string sys = sns.Substring(2, 2); 
      string subsys = sns.Substring(0, 2); 

      IEnumerable<ListViewItem> dms = getDMcollection(sys, subsys); 
      foreach(var d in dms) 
       yield return d; 

     } 
     else if (sns.Length.ToString() == "2") 
     { 
      string sys = sns.Substring(0, 2); 

      IEnumerable<ListViewItem> dms = getDMcollection(sys); 
      foreach(var d in dms) 
       yield return d; 
     } 
    } 

最後...

IEnumerable<ListViewItem> dms = newFilter.splitSNS(fullSNSpath); 

       if (dms.Any()) 
       { 

        // showfilteredList(dms); 
        foreach(var d in dms) 
         listView1.Items.Add(d); 

        showStatus(dms); 
       } 
       else 
       { 
        MessageBox.Show("There are no DMs to be displayed"); 
       } 
+0

我認爲你是對的,但我不知道如何實施你的建議。請參閱我的帖子的編輯。您能否告訴我在我的代碼中如何以及在哪裏實施您的建議。非常感謝你。 – Daedalus 2013-05-07 08:40:00

2

你想要system對應於每個dataModule s的項目,而不僅僅是第一個。

試試這個:

var dms = from dm in doc.Descendants("dataModule") 
        where dm.Element("system").Value == sys 
        select dm; 
3

正如我在評論中提到,刪除第一個(),你應該罰款:

var dms = from dm in doc.Descendants("dataModule") 
        where dm.Element("system").Value == sys 
        select dm;