c# - How do I remove a child element based on attributes on multiple parents? -


i have xml file similar structure below:

<?xml version="1.0" encoding="utf-8"?> <root attr1="foo" name="myname" attr2="bar" >     <parent1 name="is">         <child1 name="kronos1">             <grandchild1 name="word_1"/>             <grandchild2 name="word_2"/>             <grandchild3 name="word_3"/>             <grandchild4 name="word_4"/>         </child1>         <child2 name="kronos2">             <grandchild1 name="word_1"/>             <grandchild2 name="word_2"/>             <grandchild3 name="word_3"/>             <grandchild4 name="word_4"/>         </child2>     </parent1> </root> 

the elements not defined in can have different values other files. know "name" attribute of each element before hand, defined. need able manipulate, and/or delete data within selected element based on name. example: removeelement("myname.is.kronos1.word_1") delete grandchild1 element underneath child1 parent.

my issues while using linq xml queries i'm not able select element properly. using this:

private ienumerable<xelement> findelements(ienumerable<xelement> docelements, string[] names) {     // string[] array desired element removed.     // i.e. my.name.is ==> array[ "my, "name", "is"]     ienumerable<xelement> currentselection = docelements.descendants();      foreach (string name in names)     {         currentselection =             el in currentselection             el.attribute("name").value == name             select el;     }      return currentselection;  } 

to find need remove elements yields result:

<?xml version="1.0" encoding="utf-8"?> <root attr1="foo" name="myname" attr2="bar" >     <parent1 name="is">         <child1 name="kronos1">             <grandchild2 name="word_2"/>             <grandchild3 name="word_3"/>             <grandchild4 name="word_4"/>         </child1>         <child2 name="kronos2">             <grandchild2 name="word_2"/>             <grandchild3 name="word_3"/>             <grandchild4 name="word_4"/>         </child2>     </parent1> </root> 

after debugging appears i'm doing searching same document on again, different names each time. how search , select specific element based on multiple parent attribute names?

it should noted, size of xml (meaning levels of elements) variable. meaning there can little 2 levels (parents) or 6 levels (great-great-grandchildren). however, need able @ root node's name attribute well.

this should work:

if (doc.root.attribute("name").value != names.first())     throw new invalidoperationexception("sequence contains no matching element.");  var selection = doc.root;  foreach (var next in names.skip(1))     selection = selection.elements().first(x => x.attribute("name").value == next);  return selection; 

you can replace latest lines following if want to:

var selection = names.skip(1).aggregate(doc.root, (current, next) => current.elements().first(x => x.attribute("name").value == next)); 

the .first() method throws exception if no matching element found in source.


the cleanest approach add new function:

xelement selectchildelement(xelement current, string child) {     if (current == null)         return null;              var elements = current.elements();     return elements.firstordefault(x => x.attribute("name").value == child); } 

such can use following:

if (doc.root.attribute("name").value != names.first())     return null;  return names.skip(1).aggregate(doc.root, selectchildelement); 

and then, if ever need select 1 child, have handy selectchildelement() avaialble. if want myelement.selectchild(child) instead, can call extension.

also, use firstordefault here, don't exception null returned instead.

this way, doesn't have keep track of exceptions more costly...


Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -