假设我有以下文档
<sets version="2.0">
<setting>
<id>set1</id>
<value>80</value>
<label>EVersion</label>
<type>Val</type>
<format>R</format>
<bits>
<addr>0</addr>
<startBit>0</startBit>
<bitWidth>8</bitWidth>
</bitspec>
</setting>
<setting>
<id>set3</id>
<value>50</value>
<label>GVersion</label>
<type>Bin</type>
<format>R</format>
<bits>
<addr>0</addr>
<startBit>0</startBit>
<bitWidth>8</bitWidth>
</bitspec>
</setting>
</sets>
我只想要ID和值元素 -
<sets version="2.0">
<setting>
<id>set1</id>
<value>80</value>
</setting>
<setting>
<id>set3</id>
<value>50</value>
</setting>
</sets>
如何使用XDocument和LINQ选择这些?
答案 0 :(得分:2)
var xdoc = XDocument.Load(@"c:\myxml.xml");
var settings =
xdoc.Element("sets").Elements("setting")
.Select(s => new
{
Id = s.Element("id").Value,
Value = s.Element("value").Value
});
这将产生IEnumerable
匿名类型,其属性为Id
和Value
(两个字符串)。
您可以创建自己的Setting
类型,并在投影中使用它,也可以根据需要将'value'字符串值转换为整数。
答案 1 :(得分:2)
使用linq-to-xml,代码如下:
var xml_str = @"<sets version=""2.0"">
<setting>
<id>set1</id>
<value>80</value>
<label>EVersion</label>
<type>Val</type>
<format>R</format>
<bits>
<addr>0</addr>
<startBit>0</startBit>
<bitWidth>8</bitWidth>
</bits>
</setting>
<setting>
<id>set3</id>
<value>50</value>
<label>GVersion</label>
<type>Bin</type>
<format>R</format>
<bits>
<addr>0</addr>
<startBit>0</startBit>
<bitWidth>8</bitWidth>
</bits>
</setting>
</sets>";
var doc = XDocument.Parse(xml_str);
var settings = new XElement("sets",
from setting in doc.Element("sets").Elements("setting")
select new XElement("setting", setting.Element("id"), setting.Element("value")));
Console.WriteLine(settings);
打印:
<sets>
<setting>
<id>set1</id>
<value>80</value>
</setting>
<setting>
<id>set3</id>
<value>50</value>
</setting>
</sets>
如果您不需要转换XML,但只需要id -> value
映射字典(将value
存储为int
),您可以这样做:
var doc = XDocument.Parse(xml_str);
var settings_dict = doc.Element("sets").Elements("setting").ToDictionary(s => s.Element("id").Value, s => Convert.ToInt32(s.Element("value").Value));
答案 2 :(得分:0)
我的第一个答案与其他答案非常相似,并没有那么明确,所以我删除了它。但是,我认为编写一些linq将是一个很好的练习,当所需元素处于任意深度时,它会生成过滤后的XML。这就是我想出的:
Func<XElement, XElement> f = null;
f = e => e.Name == "id" || e.Name == "value" ? e : //on a match, return the node
new[] { new XElement(e.Name, e.Elements().Select(f)) } //else recurse
.FirstOrDefault(y => y.Elements().Any()); //keeping subtrees with matches
XElement resultXmlElement = f(XDocument.Parse(yourXmlString).Root);