2012-02-14 128 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);