2011-11-16 39 views
2

從下面的XML輸入:如何將LINQ to XML語句中的兄弟XElements返回?

<root> 
    <node name="one" value="1"/> 
    <node name="two" value="2"/> 
    <node name="three" value="3"/> 
    <node name="four" value="4"/> 
</root>"; 

我需要使用LINQ到XML,以產生以下:

<root> 
    <name content="one"/> 
    <value content="1"/> 
    <name content="two"/> 
    <value content="2"/> 
    <name content="three"/> 
    <value content="3"/> 
    <name content="four"/> 
    <value content="4"/> 
</root> 

此代碼將產生名稱元素,但不是元件。

var input = @" 
<root> 
    <node name=""one"" value=""1""/> 
    <node name=""two"" value=""2""/> 
    <node name=""three"" value=""3""/> 
    <node name=""four"" value=""4""/> 
</root>"; 


var xml = XElement.Parse(input); 
var query = new XElement("root", 
    from p in xml.Elements("node") 
    select new XElement("name", 
     new XAttribute("content", p.Attribute("name").Value) /*, 

     new XElement("value", new XAttribute("content", p.Attribute("value").Value)) */ 
     ) 
    ); 

如果我有最後一個括號裏面的的XElement(以上註釋),那麼它是元素的一個孩子,但右括號外面不再訪問q (它在查詢之外)。

感覺就像我需要將兩個XElements連接在一起,或者以某種方式將它們包含在另一個不產生任何XML的集合中。

回答

4

您可以使用​​將屬性弄平。在查詢格式,這是相當於兩個from clauses

var query = new XElement("root", 
    from p in xml.Elements("node") 
    from a in p.Attributes() 
    select new XElement(a.Name, 
     new XAttribute("content", a.Value) 
     ) 
    ); 

對比,使用實際SelectMany方法和書寫流利它應該是這樣的:

var query = new XElement("root", 
     xml.Elements("node") 
      .SelectMany(n => n.Attributes()) 
      .Select(a => new XElement(a.Name, 
       new XAttribute("content", a.Value)))); 

但是,我往往會發現查詢語法在大多數SelectMany用法中更清晰,我傾向於堅持一種格式或另一種格式,儘管將兩者混合都是完美的。

+0

我明白這是做什麼。現在看看我是否可以將它適應於我的真實代碼。花了我一分鐘才弄清楚。 –

+0

+1這是更優雅的方式來做到這一點。 –

2

使用您的代碼作爲起點。將這一對包裹在一個項目元素中,然後將其替換爲其子項。

 var xml = XElement.Parse(input); 
     var result = new XElement("root", 
      from p in xml.Elements("node") 
      select new XElement("item", 
         new XElement("name", new XAttribute("content", p.Attribute("name").Value)), 
         new XElement("value", new XAttribute("content", p.Attribute("value").Value)))); 

     result.Descendants("item").ToList().ForEach(n => n.ReplaceWith(n.Elements())); 
+0

啊,有創意。如果沒有第二次通過將項目替換爲其子項,這將是很好的。 。 。 –

+0

雖然@艾哈邁德的更優雅,併爲我寫的問題更好的答案,我實際上使用你的方法,因爲它更好地爲我的生產代碼工作。 –

+0

@Jim有趣......哈桑的方法有沒有增加靈活性?只是好奇:) –