[lxml-dev] Bug in objectify node[:].index
jholg at gmx.de
jholg at gmx.de
Wed May 23 09:44:25 CEST 2007
> Hi,
>
> following little script fails at the last assert:
>
> ----------------------------
> import lxml.objectify
>
>
> tree = lxml.objectify.fromstring(
> """\
> <root>
> <a name="car">foo</a>
> <a name="car">bar</a>
> <a name="tree">foo</a>
> <a name="tree">bar</a>
> </root>
> """)
>
> trees = tree.findall('//a[@name="tree"]')
> print trees
>
> foo_tree = trees[0]
> assert foo_tree.get('name') == 'tree'
>
> parent = foo_tree.getparent()
> assert parent.tag == 'root'
>
>
> node_list = parent[foo_tree.tag]
> import pdb; pdb.set_trace()
> foo_index = node_list[:].index(foo_tree)
> assert foo_index == 3, foo_index # FAILS: foo_index is 0
>
> ----------------------------
>
> So, fo_index == 0. Which is <a name="car">foo</a>. Apparently the
> .index only looks at the text or something?!
Note that you use [].index, not ObjectifiedElement.index, with the
slice you apply:
>>> node_list[:].index
<built-in method index of list object at 0x2dd558>
>>> parent.index
<built-in method index of objectify.ObjectifiedElement object at 0x1b28f0>
>>> node_list[:].index(foo_tree)
0
>>> parent.index(foo_tree)
2
>>>
Seems like [].index returns the first list item that compares equal to
its argument. As StringElements behave much like strings, this is what
happens here, as the first element in your list also has the element.text
"foo":
>>> node_list[:][0] == foo_tree
True
>>> node_list[:][1] == foo_tree
False
>>> node_list[:][2] == foo_tree
True
>>>
>>> print foo_tree.text
foo
>>> print node_list[:][0].text
foo
>>>
So I'd rather not say this is a bug...
> Anyway, all I *actually* want is to remove the nodes found by the
> xpath. The way you'd think it would be 'normal' doesn't work
> unfortunately:
>
>
> (Pdb) p parent.index(foo_tree)
> 2
> (Pdb) del parent[2]
> *** TypeError: deleting items not supported by root element
>
> This is obviously because of the sort fo strange list/attribute
> handling (i.e. parent is parent[0])
It is different from the lxml.etree (ElementTree) API but clearly stated
in the docs: Indexed access returns siblings (aka "neighbour" elements with the same name) rather than children, and every ObjectifiedElement has list behaviour; unindexed access is just a *shortcut* to retrieve the first sibling.
Cheers,
Holger
--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
More information about the lxml-dev
mailing list