【问题标题】:C# Adding multiple elements to a list using xdocumentC# 使用 xdocument 将多个元素添加到列表中
【发布时间】:2017-07-06 18:32:13
【问题描述】:
<?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,无论是上面显示的两个,还是 10 个。

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

【问题讨论】:

  • 你认为xDoc.Root.Element("fileUploadSpecification").Element("UploadBucket").Value 是做什么的?您在阅读文档时发现了什么?
  • 它获取分配给该元素的任何内容的文字值,对吗?我想我理解这一点,因为它表明该值为 "configurationtestbucket" ,这是我所期望的。我当时不明白的是,如何循环第二次,返回“UploadBucket”的第二个值->“loguploadbucket”
  • 知道你不明白它的作用,我希望你也知道。我希望您知道,如果一个方法返回的结果与您的预期完全不一致,那么您几乎肯定不了解该方法的作用。你不必在这一点上向我保证。请阅读文档。
  • 这里,我来帮忙:它返回那个名字的 first 孩子。您正在计算x。你用x 做什么?什么都没有。
  • 对,我说它正在返回我想要的第一次,但我不明白的是如何循环第二次或第三次等以返回下一次“fileUploadSpecification”元素下的一组元素

标签: c# xml linq linq-to-xml xdoc


【解决方案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();

【讨论】:

    【解决方案2】:

    每次循环时,您都会重新查找第一个 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);
    }
    

    James Curran 的答案在功能上是相同的,但形式更好。

    【讨论】:

    • 是的,FileType 是一个列表,其中包含要上传的文件类型的字符串。谢谢,这非常有帮助且内容丰富。我是 C# 和 XML/XDocument 的新手,你知道有什么好的资源可以帮助我更好地理解它吗?
    • 这是一个看起来还不错的:dotnetcurry.com/linq/564/linq-to-xml-tutorials-examples
    猜你喜欢
    • 1970-01-01
    • 2016-08-27
    • 2020-08-19
    • 2014-07-21
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    相关资源
    最近更新 更多