首先,如果您的环境是浏览器甚至是 Firefox 扩展,我建议您不要继续使用 E4X,因为他们已弃用它。
话虽这么说,在尝试做你想做的事情时,这是我在测试什么有效(很少)和什么无效时可以找到的。
尽管它很有用,而且它似乎适合过滤器/访问器语法,但删除父级(或在您的情况下为祖父级)似乎不起作用(至少当我尝试使用 Mozilla 的 E4X 引擎时) --btw,我记得,function::
下面使用的可能只在 Spidermonkey 中支持)。
var a = <a>
<b>
<c/>
</b>
</a>;
delete a.b.c.parent(); // Removing parent() will delete <c/>
alert(a); // <b/> is not deleted
因此,自然而然地,以您为例:
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></>;
...而这(使用..
后代选择器):
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...
...确实得到了<parentnode>
你想要的,像下面这样删除它是行不通的:
delete xml..*.(function::attribute('id') == "2")[0].parent().parent();
...即使这样:
delete xml..*.(function::attribute('id') == "2")[0];
...至少会删除<babynode>
您要删除的部分。
从理论上讲,我认为以下(即,没有*
选择后代的过滤元素而不是仅仅过滤祖先的标记)应该可以工作(或者至少如果这样做会很好!):
delete xml..(function::attribute('id') == "2")[0];
...但事实并非如此。
即使以这种方式访问元素(不获取后代)似乎也不起作用:
alert(xml..(function::attribute('id') == "2")[0]);
即使我们避免使用 XMLList(<></>
如果您不熟悉它,就是上面使用的简写语法)并将 XML 包装在某个命名元素中,例如<container>
,删除或访问仍然不起作用:
delete xml.container..(function::attribute('id') == "2")[0];
你可以看看http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-357.pdf看看你的阅读是否应该允许这样做,但无论如何它都不起作用,在至少我试过了。
因此,据我所知,唯一的解决方案是遍历元素并手动跟踪您的位置,而不是使用过滤器。