2012-02-14 104 views
2

比方说,我有以下文档最简单的方法

<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选择这些?

回答

2

使用LINQ到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映射字典,(存储valueint),你可以这样做:

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
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,具有属性IdValue(两个字符串)。

您可以创建自己的Setting类型,并在投影中使用该类型,并根据需要将“值”字符串值转换为整数。

0

我的第一个答案与其他答案非常相似,不太清楚,所以我删除了它。但是,我认为编写一些可以在任意深度的期望元素时生成过滤XML的linq是一个很好的练习。这是我想出了:

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