c# - Linq XML descendants being lost on enumeration -


i have xml document this

<root> <item id="1" creator="me"> <childa>1</childa> <childb>2</childb> </item> <item id="2" creator="me"> <childa>1</childa> <childb>3</childb> <childb>4</childb> </item> </root> 

i'm trying find duplicate items, again duplicate child items duplicate items logic this

xdocument xmlroot //whatever...you point // item nodes var items = xmlroot.descendants("item"); // find duplicate items keys using creator attribute var duplicateitemkeys = items.groupby(x => x.attribute("creator").value) .where(g => g.count() > 1) .select(g => g.key); foreach(var duplicateitemkey in duplicateitemkeys) { // duplicate item xml elements using duplicate keys var duplicateitems = items.where(x => x.attribute("creator").value == duplicatetouchekey) .orderby(xelement => xelement.attribute("createdon").value); } 

this works, there problem later when try use duplicateitems. time enumerates (like in foreach duplicateitems) first item looses context of it's children. second 1 fine.

so example, later in code say

var allitemb = new list<xelement>(); foreach (duplicateitem in duplicateitems) { allitemb.addrange(duplicateitem.descendants("childb")); } 

i expect "allitemb" contain 2 on first pass, 234 on second. ends happening contains 34 because once duplicateitems array enumerated first xelement looses it's children.

does know how fix this?

if understand question correctly, want allitemb have 3 elements - allitemb[0] xelement childb value 2, [1] 3 , [2] 4?

if so, problem declaring duplicateitems. code same doesn't compile, variable's scope limited first foreach loop, , not available @ second.

my code above result:

xdocument xmlroot = xdocument.load( "c:\\somefile.xml" ); // item nodes var items = xmlroot.descendants("item"); // find duplicate items keys using creator attribute var duplicateitemkeys = items.groupby(x => x.attribute("creator").value) .where(g => g.count() > 1) .select(g => g.key); ienumerable<xelement> duplicateitems = new list<xelement>(); foreach(var duplicateitemkey in duplicateitemkeys) { // duplicate item xml elements using duplicate keys duplicateitems = items.where(x => x.attribute("creator").value == duplicateitemkey) .orderby(xelement => xelement.attribute("id").value); } var allitemb = new list<xelement>(); foreach (var duplicateitem in duplicateitems) { allitemb.addrange(duplicateitem.descendants("childb")); } 

edit: forgot mention changed orderby in first foreach loop because sample xml file didn't have createdon attribute.

and if want, can use little more linq , drop foreach loops entirely, so:

xdocument xmlroot = xdocument.load( "c:\\somefile.xml" ); // item nodes var items = xmlroot.descendants("item"); // find duplicate items keys using creator attribute var duplicateitemkeys = items.groupby(x => x.attribute("creator").value) .where(g => g.count() > 1) .select(g => g.key); // duplicate item xml elements using duplicate keys var duplicateitems = items.where(i => duplicateitemkeys.contains(i.attribute("creator").value)) .orderby( xelement => xelement.attribute("id").value ); // child nodes named childb var allitemb = new list<xelement>(); allitemb.addrange( duplicateitems.descendants("childb") ); 

Comments

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

php - Get uncommon values from two or more arrays -

Adding duplicate array rows in Php -