2017-07-06 92 views
0
<?xml version="1.0" encoding="utf-8" ?> 
<root> 
    <fileUploadSpecification> 
    <DirectoryPath>C:\watchFolder</DirectoryPath> 
    <Region>us-west-2</Region> 
    <UploadBucket>configurationtestbucket</UploadBucket> 
    <FileType> 
     <type>*.txt</type> 
     <type>*.OpticomCfg</type> 
    </FileType> 
    </fileUploadSpecification> 
    <fileUploadSpecification> 
    <DirectoryPath>C:\watchFolder</DirectoryPath> 
    <Region>us-west-2</Region> 
    <UploadBucket>loguploadbucket</UploadBucket> 
    <FileType> 
     <type>*.Xml</type> 
     <type>*.Json</type> 
    </FileType> 
    </fileUploadSpecification> 
</root> 

這是我需要解析的XML文件中添加多個元素的列表,我想fileUploadSpecification的每個實例,這樣我就可以把每一組的細節到一個列表,我覺得有些類型的for循環將是合適的,我循環並添加第一組上傳細節,然後循環並添加第二組。這是我目前擁有的,但它永遠不會到達第二個fileUploadSpecification元素,它只是再次返回相同的一個。 這個想法是創造每一套fileUploadSpecification元素的新SettingsData,無論是上述兩個等所示,或10C#中使用的XDocument

public interface ISettingsEngine 
{ 

    IEnumerable<SettingsData> GetSettings(); 
} 

public class SettingsEngine : ISettingsEngine 
{ 

    public IEnumerable<SettingsData> GetSettings() 
    { 
     List<SettingsData> dataList = new List<SettingsData>(); 
     try 
     { 

      var xDoc = XDocument.Load("File1.xml"); 

      var instancesToParse = xDoc.Root.Elements().Count(); 

      var fileCount = xDoc.Root.Elements("FileType").Count(); 


      for (int x = 0; x < instancesToParse; x++) 
      { 
       var newSettingsData = new SettingsData(); 

       newSettingsData.UploadBucket = xDoc.Root.Element("fileUploadSpecification").Element("UploadBucket").Value; 
       newSettingsData.Region = xDoc.Root.Element("fileUploadSpecification").Element("Region").Value; 
       newSettingsData.DirectoryPath = xDoc.Root.Element("fileUploadSpecification").Element("DirectoryPath").Value; 
       var query = xDoc.Root.Descendants("FileType").Elements("type"); 

       foreach (XElement e in query) 
       { 
        newSettingsData.FileType.Add(e.Value); 
       } 
dataList.Add(newSettingsData); 

      } 

      return dataList; 
     } 
     catch(Exception) 
     { 
      return dataList; 
     } 
    } 
} 

public class SettingsData 
{ 

    public List<string> FileType { get; set; } 
    public string DirectoryPath { get; set; } 
    public string Region { get; set; } 
    public string UploadBucket { get; set; } 

    public SettingsData() 
    { 
     FileType = new List<string>(); 
    } 
} 
+0

您認爲'xDoc.Root.Element(「fileUploadSpecification」)。Element(「UploadBucket」)。Value是什麼?您在閱讀文檔時發現了什麼? –

+0

它獲取分配給該元素的文字值嗎?我想我明白,因爲它表明值是「配置測試桶」,這是我所期望的。我不明白的是,如何循環第二次,返回「UploadBucket」 - >「loguploadbucket」的第二個值 – John

+0

我知道你不明白它做了什麼,我希望你也知道。我希望你知道,如果一種方法返回的結果完全不符合你期望的*,那麼你幾乎肯定不明白該方法的作用。在這一點上你不必向我保證。請閱讀文檔。 –

回答

0

通過每一次循環中,你查找第一fileUploadSpecification元素再一次。您在幾個地方已經使用Elements()方法。那是你想要的。在C#中,總是傾向於使用foreach而不是for,當您循環收集數據時。它更快(編碼,而不是運行時)並且不易出錯。

foreach (var uploadSpec in xDoc.Root.Elements("fileUploadSpecification")) 
{ 
    var newSettingsData = new SettingsData(); 

    newSettingsData.UploadBucket = uploadSpec.Element("UploadBucket").Value; 
    newSettingsData.Region = uploadSpec.Element("Region").Value; 
    newSettingsData.DirectoryPath = uploadSpec.Element("DirectoryPath").Value; 

    var types = uploadSpec.Descendants("FileType").Elements("type").Select(e => e.Value); 

    foreach (var type in types) 
    { 
     newSettingsData.FileType.Add(type); 
    } 

    // Or if newSettingsData.FileType is List<String>... 
    //newSettingsData.FileType.AddRange(types); 

    dataList.Add(newSettingsData); 
} 

詹姆斯柯倫的答案在功能上是相同的,但它是更好的形式。

+0

是的,FileType是一個包含字符串的列表,這些字符串是要上傳的文件的類型。謝謝,這是非常有用的和內容豐富的。我是C#和XML/XDocument的新手,你知道有什麼好的資源可以幫助我更好地理解它嗎? – John

+0

下面是一個看起來不太糟糕的例子:http://www.dotnetcurry.com/linq/564/linq-to-xml-tutorials-examples –

1
var dataList = (from fus in xDoc.Root.Elements("fileUploadSpecification") 
      select new SettingsData 
      { 
       UploadBucket = fus.Element("UploadBucket").Value, 
       Region = fus.Element("Region").Value, 
       DirectoryPath = fus.Element("DirectoryPath").Value, 
       FileType = fus.Element("FileType") 
           .Elements("type").Select(f =>f.Value).ToList() 
      }).ToList();