[Lxml-checkins] r46515 - in lxml/trunk: . doc src/lxml src/lxml/tests
scoder at codespeak.net
scoder at codespeak.net
Wed Sep 12 22:03:38 CEST 2007
Author: scoder
Date: Wed Sep 12 22:03:37 2007
New Revision: 46515
Modified:
lxml/trunk/CHANGES.txt
lxml/trunk/doc/compatibility.txt
lxml/trunk/src/lxml/apihelpers.pxi
lxml/trunk/src/lxml/etree.pyx
lxml/trunk/src/lxml/tests/test_etree.py
Log:
accept QName objects as values for attributes and element text, and replace their namespace by the resolved prefix
Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt (original)
+++ lxml/trunk/CHANGES.txt Wed Sep 12 22:03:37 2007
@@ -8,6 +8,9 @@
Features added
--------------
+* Setting a QName object as value of the .text property or as an attribute
+ will resolve its prefix in the respective context
+
* ElementTree-like parser target interface as described in
http://effbot.org/elementtree/elementtree-xmlparser.htm
Modified: lxml/trunk/doc/compatibility.txt
==============================================================================
--- lxml/trunk/doc/compatibility.txt (original)
+++ lxml/trunk/doc/compatibility.txt Wed Sep 12 22:03:37 2007
@@ -155,6 +155,15 @@
ElementTree, you cannot pass it as a keyword argument to the Element and
SubElement factories directly.
+* ElementTree allows QName objects as attribute values and resolves their
+ prefix on serialisation (e.g. an attribute value ``QName("{myns}myname")``
+ becomes "p:myname" if "p" is the namespace prefix of "myns"). lxml.etree
+ also allows you to set attribute values from QName instances (and also .text
+ values), but it resolves their prefix immediately and stores the plain text
+ value. So, if prefixes are modified later on, e.g. by moving a subtree to a
+ different tree (which reassigns the prefix mappings), the text values will
+ not be updated and you might end up with an undefined prefix.
+
* etree elements can be copied using ``copy.deepcopy()`` and ``copy.copy()``,
just like ElementTree's. However, ``copy.copy()`` does *not* create a
shallow copy where elements are shared between trees, as this makes no sense
Modified: lxml/trunk/src/lxml/apihelpers.pxi
==============================================================================
--- lxml/trunk/src/lxml/apihelpers.pxi (original)
+++ lxml/trunk/src/lxml/apihelpers.pxi Wed Sep 12 22:03:37 2007
@@ -244,7 +244,10 @@
ns, tag = _getNsTag(key)
_attributeValidOrRaise(tag)
c_tag = _cstr(tag)
- value = _utf8(value)
+ if isinstance(value, QName):
+ value = _resolveQNameText(element, value)
+ else:
+ value = _utf8(value)
c_value = _cstr(value)
if ns is None:
tree.xmlSetProp(element._c_node, c_tag, c_value)
@@ -413,6 +416,16 @@
tree.xmlAddNextSibling(c_node, c_text_node)
return 0
+cdef _resolveQNameText(_Element element, value):
+ cdef xmlNs* c_ns
+ ns, tag = _getNsTag(value)
+ if ns is None:
+ return tag
+ else:
+ c_ns = element._doc._findOrBuildNodeNs(
+ element._c_node, _cstr(ns), NULL)
+ return '%s:%s' % (c_ns.prefix, tag)
+
cdef xmlNode* _findChild(xmlNode* c_node, Py_ssize_t index):
if index < 0:
return _findChildBackwards(c_node, -index - 1)
Modified: lxml/trunk/src/lxml/etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/etree.pyx (original)
+++ lxml/trunk/src/lxml/etree.pyx Wed Sep 12 22:03:37 2007
@@ -217,7 +217,8 @@
else:
if not _isString(text_or_uri):
text_or_uri = str(text_or_uri)
- _tagValidOrRaise(_utf8(text_or_uri))
+ tag = _getNsTag(text_or_uri)[1]
+ _tagValidOrRaise(tag)
self.text = text_or_uri
def __str__(self):
return self.text
@@ -739,10 +740,13 @@
"""
def __get__(self):
return _collectText(self._c_node.children)
-
+
def __set__(self, value):
+ if isinstance(value, QName):
+ value = python.PyUnicode_FromEncodedObject(
+ _resolveQNameText(self, value), 'UTF-8', 'strict')
_setNodeText(self._c_node, value)
-
+
property tail:
"""Text after this element's end tag, but before the next sibling
element's start tag. This is either a string or the value None, if
Modified: lxml/trunk/src/lxml/tests/test_etree.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_etree.py (original)
+++ lxml/trunk/src/lxml/tests/test_etree.py Wed Sep 12 22:03:37 2007
@@ -124,6 +124,15 @@
self.assertRaises(ValueError, QName, 'na me')
self.assertRaises(ValueError, QName, 'test', ' name')
+ def test_qname_text_resolve(self):
+ # ET doesn't resove QNames as text values
+ etree = self.etree
+ qname = etree.QName('http://myns', 'a')
+ a = etree.Element(qname, nsmap={'p' : 'http://myns'})
+ a.text = qname
+
+ self.assertEquals("p:a", a.text)
+
def test_attribute_set(self):
Element = self.etree.Element
root = Element("root")
More information about the lxml-checkins
mailing list