c# - 使用 XDocument 从带有重复键的 XML 中读取
问题描述
我需要一些关于 XDocument 的帮助。我有文件:
<?xml version="1.0" encoding="utf-8" ?>
<SaleGroupsFiles>
<SaleGroup id="1" active="true" name="US">
<files
location="c:\mypath\"
fileType="pdf"
destination="outputpath">
</files>
</SaleGroup>
<SaleGroup id="2" active="true" name="Canada">
<files
location="c:\mypath\"
fileType="pdf"
destination="outputpath">
</files>
</SaleGroup>
</SaleGroups>
我正在尝试使用 XDocument 读取文件
static Dictionary<string, string> GetSettings(string path)
{
var document = XDocument.Load(path);
var root = document.Root;
var results =
root
.Elements()
.ToDictionary(element => element.Name.ToString(), element => element.Value);
return results;
}
收到错误“字典中已存在具有该键的元素”。我猜这是因为“SaleGroup”重复了不止一次。
读取数据的正确方法是什么?
解决方案
你的假设是正确的;正如@maccettura 解释的那样,这就是Dictionary
工作原理。
这就是说,请记住,<SaleGroupsFiles>
您的 XML 应该有一个匹配的标记才能有效。
根据您的问题,这是一个可能的想法:
var results =
root
.Descendants("SaleGroup")
.ToDictionary(element => element.Attribute("id").Value.ToString(), element => element.ToString());
即添加元素属性的值作为键id
,假设它们是唯一的。
其实这个问题
读取数据的正确方法是什么?
很难回答,因为......这取决于你想对数据做什么。你想创建SaleGroup
对象吗?List<SaleGroup>
在这种情况下,如果你提供一个SaleGroup
类,你可以创建一个,而不是创建一个字典。
另一种选择是反序列化您的 XML。
另外,请记住 element.Name 将给出元素的名称(例如 SaleGroup),而您可能想读取name
属性的值(例如“Canada”)?
编辑
由于您可以使用稍微更现实的解决方案,如果您声明这些类
public class SaleGroup
{
public int Id { get; set; }
public bool Active { get; set; }
public string Name { get; set; }
public SaleFile File { get; set; }
}
public class SaleFile
{
public string Location { get; set; }
public string FileType { get; set; }
public string Destination { get; set; }
}
你可以这样编辑你的代码:
var results =
root
.Descendants("SaleGroup")
.Select(element => new SaleGroup()
{
Active = Convert.ToBoolean(element.Attribute("active").Value),
Id = Convert.ToInt32(element.Attribute("id").Value),
Name = element.Attribute("name").Value,
File = new SaleFile()
{
Destination = element.Descendants("files").Single().Attribute("destination").Value,
FileType = element.Descendants("files").Single().Attribute("fileType").Value,
Location = element.Descendants("files").Single().Attribute("location").Value
}
})
.ToList();
也可以优化上面的代码,例如只读取element.Descendants("files").Single()
一次,或者修改它以允许SaleFile
在你的SaleGroup
类中使用多个。
推荐阅读
- gstreamer - 从 gst-launch-1.0 管道发出(动作)信号
- ios - UICollectionView 包括 2 个部分,其中一个是 gird,另一个是列表 - swift
- java - 带有重载的 Java 函数调用
- freertos - 在一项任务中传输接收
- android - 在 Android webView 中使用最新的浏览器功能
- javascript - indexOf 函数中的选项之间的选择
- reactjs - 浏览器缓存未在 Cloudfront 上加载新版本的 ReactJS 单页应用程序
- git - 带有 SSH 主机别名的 git clone
- c - MCP2515 和 STM32L053:SPI 问题
- django - 图像未在 Django 中上传