2013-02-15 23 views
1

我的第二篇文章在同一天晚上,道歉!使用LINQ to XML從XML文件中檢索多個屬性,寫入每行到

我有一個XML文件,其中包含幾個信息的各種軟件條目(片段見下文)。

<software> 
    <software_entry 
    name="Adobe Acrobat X Standard" 
    path="Applications\Acrobat\Acrobat X Standard\AcroStan.msi" 
    type="msi" 
    switches="/qn ALLUSERS=1" 
    /> 
    <software_entry 
    name="Adobe Acrobat X Professional" 
    path="Applications\Acrobat\Acrobat X Pro\AcroPro.msi" 
    type="msi" 
    switches="/qn ALLUSERS=1" 
    /> 
</software> 

我正在使用LINQ to XML來加載XML文件。在我的應用程序中,我有兩個列表框,其中第一個列表框(listBox1)填充了此XML文件中每個條目的名稱。用戶然後可以將這些條目從一個列表框移動到另一個列表框(listBox2)。

我想寫一個方法遍歷listBox2中的每個條目,找到XML文件中的匹配條目,然後檢索該條目的所有其他屬性。例如,用戶已將Adobe Acrobat X Professional添加到第二個列表框。該方法應查看XML文件,找到名稱爲「name」的條目,它與列表中的內容匹配,並寫入其他數據(路徑,類型,開關)或將它們設置爲字符串的值。到目前爲止,經過很多調整後,我取得了一些成績。我設法得到了一些非常亂碼的輸出。

我的代碼到目前爲止如下。

private void writeBatchFile() 
{ 
    // Get temp folder location 
    string tempPath = Path.GetTempPath(); 

    // Create batch file 
    using (StreamWriter writer = File.CreateText(tempPath + @"\swInstaller.cmd")) 
    { 
     // Loop through entries in listBox2 
     foreach (string item in listBox2.Items) 
     { 
      var dataFromXML = from data in document.Descendants("software_entry") 
           where data.Element("name").Value == item 
           select new 
           { 
            fileName = (string) data.Element("name"), 
            filePath = (string) data.Element("path"), 
            fileType = (string) data.Element("type"), 
            fileSwitches = (string) data.Element("switches") 
           }; 

      // Write to batch file 
      writer.WriteLine(fileName + filePath + fileType + fileSwitches); 
     } 
    } 
} 

在代碼中,我有一個foreach循環,用於listBox2中的文本值。然後,我試圖找到該值等於XML中「名稱」值的位置,然後在此值時將該值的其他屬性設置爲這些字符串(filePath for path,fileType for type等)。最後,我試圖將這些字符串寫入文本文件。有了這個特別的嘗試,我得到的只有5個空白行。有人可以指出我正確的方向,我做錯了什麼?

非常感謝。

回答

2

您正在嘗試讀取XML屬性,而不是元素。使用Attribute方法代替:

var dataFromXML = Enumerable.Single 
(
    from data in document.Descendants("software_entry") 
    where data.Attribute("name").Value == item 
    select new 
    { 
     fileName = data.Attribute("name").Value, 
     filePath = data.Attribute("path").Value, 
     fileType = data.Attribute("type").Value, 
     fileSwitches = data.Attribute("switches").Value 
    } 
); 

writer.WriteLine(dataFromXML.fileName); 

您還需要使這些額外的變化:

  • 使用Enumerable.Single()表明,你只希望1個元素匹配給定的名稱。否則dataFromXML可能包含多個元素,您需要使用循環或索引來訪問它們。
  • 您需要訪問fileName和其他變量作爲dataFromXML變量的成員。沒有自己的局部變量,所以這就是爲什麼你會收到你提到的錯誤信息。
  • 您不需要強制轉換爲string,因爲默認情況下,從XML屬性讀取的值已經是字符串。
+0

感謝您的回覆。我的循環在邏輯上有效嗎? 我得到fileName,filePath等,不存在於當前上下文中。我/你寫的代碼是否真的把它們設置爲字符串,還是我還需要做別的事情? 我已經編輯了一下我的代碼 - 我只是希望在測試階段將所有代碼都寫入一行,並且稍後將對其進行格式化。 – CSF90 2013-02-15 23:37:59

+0

是的,你需要做更多的改變。我編輯了我的答案。 – 2013-02-16 00:18:50

+0

非常感謝! – CSF90 2013-02-16 01:18:47