Как вернуть родственные элементы XElements в операторе LINQ to XML? - PullRequest
2 голосов
/ 16 ноября 2011

Из следующего XML-ввода:

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

Мне нужно использовать 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>

Этот код создает элементы name , но не элементы value .

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 (закомментированное выше) внутри последней скобки, то это дочерний элемент элемента name , но за пределами закрывающей скобки он больше не имеет доступа на q (вне запроса).

Такое ощущение, что мне нужно объединить два элемента XElements вместе или как-то включить их в другую коллекцию, которая не создает XML.

Ответы [ 2 ]

4 голосов
/ 16 ноября 2011

Вы можете сгладить атрибуты, используя метод Enumerable.SelectMany .В формате запроса это эквивалентно двум 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)
        )
    );

Для сравнения, использование фактического метода 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, и я склонен придерживаться того или иного формата, хотя прекрасно сочетать оба.

2 голосов
/ 16 ноября 2011

Использование вашего кода в качестве отправной точки. Оберните пару в элементе 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()));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...