XElement.Descendants ( “nodo”) no se comporta como se esperaba, devuelve varios niveles de Descendientes

StackOverflow https://stackoverflow.com/questions/1753518

  •  20-09-2019
  •  | 
  •  

Pregunta

Tengo un problema. Tengo datos XML jerárquicos tales como:

<Tree>
  <Node Text="Stuff" ItemGUID="064a9bf0-0594-47f8-87be-88dd73763c77" >
    <Node Text="Food" ItemGUID="326f1f7a-d364-4838-9bdc-ce5fd93f88ca" ItemType="2" />
    <Node Text="Wines" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
    <Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
        <Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f">
              <Node Text="Red" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
              <Node Text="Pink" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
              <Node Text="White" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
        </Node>
        <Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
        <Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
    </Node>
    <Node Text="Sweet Delights" ItemGUID="1df7dbae-adf0-49a9-aaac-1358468a245b" />
  </Node>
</Tree>

Y necesito para obtener sólo las flores (rosas, tulipanes, lo que) SIN rojo, rosado, blanco (debajo de las rosas)  Estoy usando el siguiente código, pero debido al hecho de que todos los nodos son "nodo" Puedo obtener todos los niveles de Descendats. Me gustaría limitar a un solo nivel.

XElement loadedXML = clients.ItemTreeXML;

//filter only current node
XElement procXML;
procXML = new XElement ("Tree",
          from el in loadedXML.Descendants("Node")
          where (string)el.Attribute("ItemGUID") == currentNodeGUID
          select el); 

Resultado Se busca:

<Tree>
        <Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
            <Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
            <Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
            <Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
        </Node>
</Tree>

Gracias,

Alta: Tal vez una consulta SQL 2008 podría retreive solamente la rama nodo que necesito, pero después de mucha investigación y pruebas, no pude encontrar una respuesta ... (Mi XML está en una columna XML en SQL 2008)

¿Fue útil?

Solución

Así que tenemos esto ...

XElement loadedXML = XElement.Load("test.xml");

//filter only current node
XElement procXML;
procXML = new XElement("Tree",
    from el in loadedXML.Descendants("Node")
    where (string)el.Attribute("ItemGUID") == currentNodeGUID
    select el);

La mejor manera que he encontrado era eliminar todos los elementos secundarios después de hacer la consulta LINQ. De esta manera:

foreach (XElement xl in procXML.Element("Node").Elements("Node"))
{
    if (xl.HasElements) // just remove the ones without child elements
    {
        xl.RemoveNodes();
    }
}

Esto dará salida a lo que has deseado, pero debo añadir ... Hay más definitivamente posible una mejor manera de hacer esto. No sé lo bien que va a trabajar con su situación dada la mayoría de las necesidades de código escrito para trabajar de forma más dinámica que esto.

vi esta cuestión y decidió tomar una inmersión en LINQ, que supongo que no era tan malo. Si eso no funciona de la manera que necesita, por lo menos es un comienzo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top