使用 XDocument 使用重复键从 XML 中读取
Reading from XML with repeated keys using XDocument
我需要 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;
}
出现错误 "element with that key already exists in dictionary"。我猜这是因为 "SaleGroup" 重复了不止一次。
读取数据的正确方法是什么?
你的推测是正确的;正如@maccettura 所解释的,这就是 Dictionary
的工作原理。
这就是说,请记住 <SaleGroupsFiles>
应该有一个匹配的标签以使您的 XML 有效。
根据你的问题,这是一个可能的想法:
var results =
root
.Descendants("SaleGroup")
.ToDictionary(element => element.Attribute("id").Value.ToString(), element => element.ToString());
即添加元素的 id
属性的值作为键,假设它们是唯一的。
其实这个问题
What is the proper way to read the data?
很难回答,因为...这取决于您要对数据执行的操作。
您要创建 SaleGroup
个对象吗?在这种情况下,如果您提供 SaleGroup
class.
,则无需创建字典,只需创建 List<SaleGroup>
另一种选择是 deserializing 你的 XML。
此外,请记住 element.Name 将给出元素的名称(例如 SaleGroup),而您可能想要读取 name
属性的值(例如 "Canada") ?
编辑
既然你可以接受稍微现实一点的解决方案,如果你声明这些 classes
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()
一次,或修改它以在 SaleGroup
class.
中允许多个 SaleFile
我需要 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;
}
出现错误 "element with that key already exists in dictionary"。我猜这是因为 "SaleGroup" 重复了不止一次。
读取数据的正确方法是什么?
你的推测是正确的;正如@maccettura 所解释的,这就是 Dictionary
的工作原理。
这就是说,请记住 <SaleGroupsFiles>
应该有一个匹配的标签以使您的 XML 有效。
根据你的问题,这是一个可能的想法:
var results =
root
.Descendants("SaleGroup")
.ToDictionary(element => element.Attribute("id").Value.ToString(), element => element.ToString());
即添加元素的 id
属性的值作为键,假设它们是唯一的。
其实这个问题
What is the proper way to read the data?
很难回答,因为...这取决于您要对数据执行的操作。
您要创建 SaleGroup
个对象吗?在这种情况下,如果您提供 SaleGroup
class.
List<SaleGroup>
另一种选择是 deserializing 你的 XML。
此外,请记住 element.Name 将给出元素的名称(例如 SaleGroup),而您可能想要读取 name
属性的值(例如 "Canada") ?
编辑
既然你可以接受稍微现实一点的解决方案,如果你声明这些 classes
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()
一次,或修改它以在 SaleGroup
class.
SaleFile