Alex Klizhentas | 2 May 19:21

Re: Custom Elements question

Thanks Stefan,

All the nodes in that tree should have the same type, that's why the default class lookup scheme for parser works fine.

BTW, I have one more question, to set the xml:id i use the following construct:

def xml_id(v):
    # helper function to create name space attributes
    return {'{http://www.w3.org/XML/1998/namespace}id': v}

and the following construct:

N.child1("text",xml_id("some_id"))

following the examples from the site.

to get the id I use:

class NodeBase(etree.ElementBase):
    ...   
    def get_node_id(self,id):
        searched = self.find(".//*[ <at> {http://www.w3.org/XML/1998/namespace}id='%s']"%(id,))
        if searched is None:
            raise NodeNotFoundError(id)
        return searched


I have two questions:

1. what way is faster to get the element by Id? should I use find or xpath to achieve the better performance?
2. is there a way to set xml:id using xml - prefix?

Thanks,
Alex

2008/5/2 Stefan Behnel <stefan_ml <at> behnel.de>:
Hi,

another bit of reasoning here.

Stefan Behnel wrote:
> Alex Klizhentas wrote:
>> I've extended the ElementBase object using the approach described in the
>> tutorial, but SubElement does not work as desired:
>>
>> class NodeBase(etree.ElementBase):
>>      def append(self,child):
>>  print "aaa"
>>  return etree.ElementBase.append(self,child)
>>
>> etree.SubElement(root,"child") #no "aaa" printed
>
> That's because SubElement() does not call .append().
[...]
> SubElement() does not call .makeelement() either. It's implemented in plain C.

One important reason is that this allows lxml.etree to append the new libxml2
node at the C level *before* the decision is taken which Python class should
be used to represent it. This might have an impact on the class lookup if it
considers the parental relation when taking its decision (lxml.objectify does
that, for example).

But that's the only difference I can see between etree.SubElement() and your
Python implementation. And you could even work around it by doing something
like this:

def SubElement(parent, tag, attrib={}, **extra):
    attrib = attrib.copy()
    attrib.update(extra)
    element = parent.makeelement(tag, attrib)
    parent.append(element)
    del element
    return parent[-1]

However, you might want to avoid that if you know you won't need it, e.g. when
using the "namespace" or "default" lookup scheme.

Stefan




--
Regards,
Alex
_______________________________________________
lxml-dev mailing list
lxml-dev <at> codespeak.net
http://codespeak.net/mailman/listinfo/lxml-dev

Gmane