First off, if your environment is the browser or even a Firefox extension, I'd advise against continuing with E4X as they have deprecated it.
That being said, here is what I could find in testing around about what works (very little) and what does not, in attempting to do what you are trying to do.
As useful as it would be, and as well as it seems it would fit into the filter/accessor syntax, deleting a parent (or grand-parent in your case) does not seem to work (at least when I try with Mozilla's E4X engine--btw, as I recall, the function::
used below might only be supported in Spidermonkey).
var a = <a>
<b>
<c/>
</b>
</a>;
delete a.b.c.parent(); // Removing parent() will delete <c/>
alert(a); // <b/> is not deleted
Thus naturally, in taking your example:
var xml = <><parentnode>
<childnode>
<babynode id="1">
<parameter>goes here</parameter>
</babynode>
</childnode>
</parentnode>
<parentnode>
<childnode>
<babynode id="2">
<parameter>goes here</parameter>
</babynode>
</childnode>
</parentnode></>;
...while this (using the ..
descendant selector):
alert(xml..*.(function::attribute('id') == "2")[0].parent().parent()); // I'm also not sure why the formatting of the attribute cannot be obtained by `xml..*.(@id == "2")` without giving an error since id is not a reserved word, but anyways...
...does get the <parentnode>
you want, deleting it like in the following does not work:
delete xml..*.(function::attribute('id') == "2")[0].parent().parent();
...even while this:
delete xml..*.(function::attribute('id') == "2")[0];
...will at least delete the <babynode>
part you want to delete.
Theoretically, I would think that the following (i.e., without the *
mark which selects the filtered elements of descendants instead of just filtering the ancestor) should work (or at least it would be nice if it did!):
delete xml..(function::attribute('id') == "2")[0];
...yet it does not.
Even accessing an element in this manner (of not grabbing a descedant) does not seem to work:
alert(xml..(function::attribute('id') == "2")[0]);
And even if we avoid using an XMLList (<></>
being the short-hand syntax used above if you were not familiar with it) and wrap the XML in some named element, say <container>
, deleting or accessing still does not work:
delete xml.container..(function::attribute('id') == "2")[0];
You could take a look at http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-357.pdf to see if your reading should allow this, but in any case it does not work, at least as I've tried it.
So, as far as I can see, the only solution would be to iterate through the elements and track where you are manually rather than using filters.