我试图使用XDocument解析xml文档,但是我对XML非常陌生,过去只使用过JSON。到目前为止,我可以解析每个报表名,但仍然无法解析参数列表。当没有节点区分不同的参数时,如何解析参数列表?
var reports = xml.Descendants("Report").Select(reportElement => new
{
Name = reportElement.Attribute("Name").Value,
Parameters = reportElement.Descendants("ParameterList").Select(parameter => new
{
})
});XML:
<ReportList>
<Report Name="JobNotClose">
<ParameterList>
<Name>@StationCode</Name><Value>LAX</Value>
<Name>@ShipmentType</Name><Value>SE|SI</Value>
</ParameterList>
</Report>
<Report Name="JobWithoutSales">
<ParameterList>
<Name>@StationCode</Name><Value>PA</Value>
<Name>@JobDateFrom</Name><Value>2013-10-1</Value>
<Name>@JobDateTo</Name><Value>2013-10-31</Value>
</ParameterList>
</Report>
</ReportList>发布于 2013-12-17 10:28:46
可以使用Enumerable.Zip将参数名称序列与参数值序列合并:
var reports = from r in xml.Root.Elements("Report")
let parameters = r.Element("ParameterList")
select new {
Name = (string)r.Attribute("Name"),
Parameters = parameters.Elements("Name")
.Zip(parameters.Elements("Value"),
(n,v) => new {
Name = (string)n,
Value = (string)v
})
};这提供了以下报告的收集:
[
{
"Name": "JobNotClose",
"Parameters": [
{
"Name": "@StationCode",
"Value": "LAX"
},
{
"Name": "@ShipmentType",
"Value": "SE|SI"
}
]
},
{
"Name": "JobWithoutSales",
"Parameters": [
{
"Name": "@StationCode",
"Value": "PA"
},
{
"Name": "@JobDateFrom",
"Value": "2013-10-1"
},
{
"Name": "@JobDateTo",
"Value": "2013-10-31"
}
]
}
]发布于 2013-12-17 10:03:47
试试这个(我的意思是使用):
var reports = xml.Descendants("Report").Select(reportElement => new
{
Name = reportElement.Attribute("Name").Value,
Parameters = reportElement.Descendants("ParameterList").Select(parameter =>
{
List<string> names = parameter.Elements("Name").Select(x=>x.Value).ToList();
List<string> values = parameter.Elements("Value").Select(x=>x.Value).ToList();
List<object> pairs=new List<object>();
for (int i = 0; i < names.Count; i++)
{
pairs.Add(new { Name = names[i], Value = values[i] });
}
return pairs;
}).ToList()
}).ToList();您可以删除两个ToList()调用。这只会让它更容易测试。当然,在您的XML中,<Name> <Value>标记并不总是完整的(即没有Value的Name )。您可以在执行for循环之前检查它。
编辑:另一种选择:
Dictionary<string, List<Tuple<string, string>>> rep = new Dictionary<string, List<Tuple<string, string>>>();
foreach (XElement report in xml.Elements("Report"))
{
rep.Add(report.Attribute("Name").Value, new List<Tuple<string, string>>());
List<string> names = report.Elements("ParameterList").FirstOrDefault().Elements("Name").Select(x => x.Value).ToList();
List<string> values = report.Elements("ParameterList").FirstOrDefault().Elements("Value").Select(x => x.Value).ToList();
for (int i = 0; i < names.Count; i++)
{
rep[report.Attribute("Name").Value].Add(new Tuple<string, string>(names[i], values[i]));
}
}发布于 2013-12-17 10:01:58
也许这会奏效。
您可以使用ParameterList将IEnumerable元素作为XNode.ElementsAfterSelf。然后循环遍历结果集,并假定元素成对。
这将为您提供一种按元素在ParameterList中出现的顺序解析元素的方法,而不必担心.Descendants会扰乱顺序。
当然,这里最大的假设是元素总是成对的。
https://stackoverflow.com/questions/20630641
复制相似问题