简体   繁体   English

如何在LINQ to XML语句中返回同级XElement?

[英]How to return sibling XElements in a LINQ to XML statement?

From the following XML input: 从以下XML输入:

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

I need to use LINQ to XML to produce the following: 我需要使用LINQ to 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>

This code produces the name elements, but not the value elements. 此代码生成名称元素,但不生成元素。

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

If I include the value XElement (commented out above) inside the last parenthesis then it is a child of the name element, but outside the closing parenthesis it no longer has access to q (it is outside the query). 如果我在最后一个圆括号内包括 XElement(在上面注释),则它是name元素的子级,但是在右圆括号之外,它不再可以访问q (它在查询之外)。

It feels like I need to concatenate two XElements together or somehow include them in another collection that doesn't produce any XML. 感觉我需要将两个XElement连接在一起,或者以某种方式将它们包含在另一个不产生任何XML的集合中。

You could flatten the attributes using the Enumerable.SelectMany method . 您可以使用Enumerable.SelectMany方法展平属性。 In query format this is equivalent to two from clauses : 在查询格式中,这等效于两个from子句

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

To contrast, using the actual SelectMany method and writing it fluently would look like this: 相比之下,使用实际的SelectMany方法并流畅地编写它看起来像这样:

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

However, I tend to find the query syntax to be clearer in most of SelectMany usages and I tend to stick to one format or another, although it's perfectly fine to mix both. 但是,我倾向于发现大多数SelectMany用法中的查询语法都更清晰,并且我倾向于坚持一种或另一种格式,尽管将两种格式混合使用都很好。

Using your code as starting point. 以您的代码为起点。 Wrap the pair in an item element and then replace it with its children. 将对包裹在item元素中,然后将其替换为其子项。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM