[Lxml-checkins] r38403 - in lxml/trunk: . src/lxml src/lxml/tests

scoder at codespeak.net scoder at codespeak.net
Sat Feb 10 18:36:08 CET 2007


Author: scoder
Date: Sat Feb 10 18:36:06 2007
New Revision: 38403

Modified:
   lxml/trunk/CHANGES.txt
   lxml/trunk/src/lxml/tests/test_xslt.py
   lxml/trunk/src/lxml/xslt.pxi
Log:
get()/set() methods for PI elements

Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt	(original)
+++ lxml/trunk/CHANGES.txt	Sat Feb 10 18:36:06 2007
@@ -8,8 +8,10 @@
 Features added
 --------------
 
-* ElementInclude module for ElementTree compatible XInclude processing that
-  honours custom resolvers registered with the source document
+* get/set emulation (not .attrib!) for attributes on processing instructions
+
+* ElementInclude Python module for ElementTree compatible XInclude processing
+  that honours custom resolvers registered with the source document
 
 * ElementTree.parser property holds the parser used to parse the document
 

Modified: lxml/trunk/src/lxml/tests/test_xslt.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_xslt.py	(original)
+++ lxml/trunk/src/lxml/tests/test_xslt.py	Sat Feb 10 18:36:06 2007
@@ -599,7 +599,7 @@
         style_root = tree.getroot().getprevious().parseXSL().getroot()
         self.assertEquals("{http://www.w3.org/1999/XSL/Transform}stylesheet",
                           style_root.tag)
-        
+
     def test_xslt_pi_embedded_xmlid(self):
         # test xml:id dictionary lookup mechanism
         tree = self.parse('''\
@@ -628,7 +628,7 @@
 <foo>B</foo>
 ''',
                           st.tostring(res))
-        
+
     def test_xslt_pi_embedded_id(self):
         # test XPath lookup mechanism
         tree = self.parse('''\
@@ -663,6 +663,88 @@
 ''',
                           st.tostring(res))
 
+    def test_xslt_pi_get(self):
+        tree = self.parse('''\
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="TEST"?>
+<a>
+  <b>B</b>
+  <c>C</c>
+</a>''')
+
+        pi = tree.getroot().getprevious()
+        self.assertEquals("TEST", pi.get("href"))
+
+    def test_xslt_pi_get_all(self):
+        tree = self.parse('''\
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="TEST"?>
+<a>
+  <b>B</b>
+  <c>C</c>
+</a>''')
+
+        pi = tree.getroot().getprevious()
+        self.assertEquals("TEST", pi.get("href"))
+        self.assertEquals("text/xsl", pi.get("type"))
+        self.assertEquals(None, pi.get("motz"))
+
+    def test_xslt_pi_get_all_reversed(self):
+        tree = self.parse('''\
+<?xml version="1.0"?>
+<?xml-stylesheet href="TEST" type="text/xsl"?>
+<a>
+  <b>B</b>
+  <c>C</c>
+</a>''')
+
+        pi = tree.getroot().getprevious()
+        self.assertEquals("TEST", pi.get("href"))
+        self.assertEquals("text/xsl", pi.get("type"))
+        self.assertEquals(None, pi.get("motz"))
+
+    def test_xslt_pi_get_unknown(self):
+        tree = self.parse('''\
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="TEST"?>
+<a>
+  <b>B</b>
+  <c>C</c>
+</a>''')
+
+        pi = tree.getroot().getprevious()
+        self.assertEquals(None, pi.get("unknownattribute"))
+
+    def test_xslt_pi_set_replace(self):
+        tree = self.parse('''\
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="TEST"?>
+<a>
+  <b>B</b>
+  <c>C</c>
+</a>''')
+
+        pi = tree.getroot().getprevious()
+        self.assertEquals("TEST", pi.get("href"))
+
+        pi.set("href", "TEST123")
+        self.assertEquals("TEST123", pi.get("href"))
+
+    def test_xslt_pi_set_new(self):
+        tree = self.parse('''\
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl"?>
+<a>
+  <b>B</b>
+  <c>C</c>
+</a>''')
+
+        pi = tree.getroot().getprevious()
+        self.assertEquals(None, pi.get("href"))
+
+        pi.set("href", "TEST")
+        self.assertEquals("TEST", pi.get("href"))
+
     def test_exslt_regexp_test(self):
         xslt = etree.XSLT(etree.XML("""\
 <xsl:stylesheet version="1.0"

Modified: lxml/trunk/src/lxml/xslt.pxi
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxi	(original)
+++ lxml/trunk/src/lxml/xslt.pxi	Sat Feb 10 18:36:06 2007
@@ -550,8 +550,17 @@
 ################################################################################
 # XSLT PI support
 
+cdef object _FIND_PI_ATTRIBUTES
+_FIND_PI_ATTRIBUTES = re.compile(r'\s+(\w+)\s*=\s*["\']([^"\']+)["\']', re.U).findall
+
+cdef object _RE_PI_HREF
+_RE_PI_HREF = re.compile(r'\s+href\s*=\s*["\']([^"\']+)["\']')
+
 cdef object _FIND_PI_HREF
-_FIND_PI_HREF = re.compile('href\s*=\s*["\']([^"\']+)["\']').findall
+_FIND_PI_HREF = _RE_PI_HREF.findall
+
+cdef object _REPLACE_PI_HREF
+_REPLACE_PI_HREF = _RE_PI_HREF.sub
 
 cdef XPath _findStylesheetByID
 _findStylesheetByID = XPath(
@@ -574,7 +583,7 @@
         cdef xmlAttr* c_attr
         if self._c_node.content is NULL:
             raise ValueError, "PI lacks content"
-        hrefs_utf = _FIND_PI_HREF(self._c_node.content)
+        hrefs_utf = _FIND_PI_HREF(' ' + self._c_node.content)
         if len(hrefs_utf) != 1:
             raise ValueError, "malformed PI attributes"
         href_utf = hrefs_utf[0]
@@ -610,6 +619,26 @@
         result_node = root[0]
         return _elementTreeFactory(result_node._doc, result_node)
 
+    def set(self, key, value):
+        if key != "href":
+            raise AttributeError, "only setting the 'href' attribute is supported on XSLT-PIs"
+        if value is None:
+            attrib = ""
+        elif '"' in value or '>' in value:
+            raise ValueError, "Invalid URL, must not contain '\"' or '>'"
+        else:
+            attrib = ' href="%s"' % value
+        text = ' ' + self.text
+        if _FIND_PI_HREF(text):
+            self.text = _REPLACE_PI_HREF(attrib, text)
+        else:
+            self.text = text + attrib
+
+    def get(self, key, default=None):
+        for attr, value in _FIND_PI_ATTRIBUTES(' ' + self.text):
+            if attr == key:
+                return value
+        return default
 
 ################################################################################
 # EXSLT regexp implementation


More information about the lxml-checkins mailing list