Limitations of attribute nodes in Python

Marc-Antoine Parent <[email protected]> Mon, 15 Mar 2004 23:43:45 -0500
Newsgroups gmane.comp.gnome.lib.xml.bindings
Message-ID <[email protected]>
I was coding up an XUpdate implementation in Python, and I realized  
that, when a XPath gave me an attribute node, there was actually very  
little I could do with it.

A) For example, if I change the content, it will have no effect on the  
owning node.

 >>> import sys
 >>> from libxml2 import *
 >>> xmlText="""<a b="x"/>"""
 >>> doc = parseMemory(xmlText,len(xmlText))
 >>> doc
<xmlDoc (None) object at 0x74468>
 >>> rootElement=doc.getRootElement()
 >>> rootElement
<xmlNode (a) object at 0x6d3a0>
 >>> b=rootElement.get_properties()
 >>> b
<xmlAttr (b) object at 0x255968>
 >>> b.content
'x'
 >>> b.content='y'
 >>> b.content
'y'
 >>> doc.dump(sys.stdout)
<?xml version="1.0"?>
<a b="x"/>
33

B) So I thought I would go back to the parent to do a setProp, which is  
slightly hassly, but then I realized I do not have an easy access to  
the parent!
 >>> b.parent
 >>> b.get_parent()
 >>>

Of course, I can do this, which fortunately works, but is somewhat  
heavy-handed:

 >>> b.xpathEval("..")
[<xmlNode (a) object at 0x255a08>]

C) I tried other ways to obtain the parent; some failed, and some  
worked: I do not pretend I always knew what I was doing, there, and I  
am sure some of this is not expected to work, but the bus error in my  
final attempt still came as a slight shock.

 >>> c = doc.xpathNewContext()
 >>> c.setContextNode(b)
 >>> c.xpathEval("..")
[<xmlNode (a) object at 0x74fd0>]
 >>> b.xpathNextParent(c)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File  
"/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ 
python2.3/site-packages/libxml2.py", line 3455, in xpathNextParent
     if ret is None:raise xpathError('xmlXPathNextParent() failed')
libxml2.xpathError: xmlXPathNextParent() failed
 >>> b.xpathEval("..")
[<xmlNode (a) object at 0x255a08>]
 >>> c.setContextNode(b)
 >>> pc=c.xpathNewParserContext("")
 >>> pc.xpathNextParent(b)
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File  
"/System/Library/Frameworks/Python.framework/Versions/2.3/lib/ 
python2.3/site-packages/libxml2.py", line 5501, in xpathNextParent
     if ret is None:raise xpathError('xmlXPathNextParent() failed')
libxml2.xpathError: xmlXPathNextParent() failed
 >>> pc.xpathNextAncestor(b)
<xmlNode (a) object at 0x74ee0>
 >>> b.xpathNextAncestor(c)
Bus error

I settled on pc.xpathNextAncestor(b) as plausibly the most efficient.

Please tell me if you want me to bugzilla A, B, C separately or as a  
block. Also, if some of them do feel normal to you, I would like to  
understand why.

Marc-Antoine Parent