Linq xml recursive select -


<nodes>   <node>     <id>1</id>     <tids>       <tid>2</tid>       <tid>3</tid>     </tids>   </node>   <node>     <id>2</id>     <tids>       <tid>4</tid>     </tids>   </node>   <node>     <id>3</id>     <tids>       <tid>7</tid>     </tids>   </node>   <node>     <id>4</id>     <tids>       <tid>7</tid>     </tids>   </node>   <node>     <id>5</id>     <tids>       <tid>7</tid>     </tids>   </node>   <node>     <id>6</id>     <tids>       <tid>7</tid>     </tids>   </node>   <node>     <id>7</id>   </node> </nodes> 

i want write query fselect tid , again query xml select it's tid suppose condition id equal 1 want out put 2,3,4,7 in condition if put id equal 5 put put 7 how write recursive linq

recursive linq more of party trick you'd want use in production code, here's 1 way it:

xelement nodes = /* load xml */;  func<xelement, int, ienumerable<int>> query = null;  /* bad code, not use! */ query = (x,id) =>     x.elements("node")      .where (node => (int)node.element("id") == id) // find our node      .descendants("tid")      // empty in base case      .select (tid => (int)tid)      .selectmany(tid =>         query(x,tid)           // recurse        .concat(new[]{tid})    // keep current tid if node had no tids      )      .distinct();  var resultof7423 = query(nodes, 1); var resultof7 = query(nodes, 5); /* end bad code (i hope) */ 

this baffling , fragile code, , shouldn't use it. instead, create extension method off of xelement:

public static ienumerable<int> selectrelatedids(this xelement element, int id) {     if(element == null) throw new argumentnullexception("element");     return selectrelatedidsiterator(element, id)                 .where(i => != id)                 .distinct(); }  private static ienumerable<int> selectrelatedidsiterator(xelement element, int id) {     yield return id;      var tids = element.elements("node")                 .where (node => (int)node.element("id") == id)                 .descendants("tid");      foreach (int tid in tids)         foreach(var in  selectrelatedidsiterator(element, tid))             yield return i; } 

this keeps recursion contained , pretty easy understand (at least once head around iterator blocks). it's linq-friendly , potentially composable in way first way not.


Comments

Popular posts from this blog

php - get table cell data from and place a copy in another table -

javascript - Mootools wait with Fx.Morph start -

php - Navigate throught databse rows -