def test_thread_xslt_attr_replace(self): # this is the only case in XSLT where the result tree can be # modified in-place XML = self.etree.XML tostring = self.etree.tostring style = self.etree.XSLT( XML( _bytes( """\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <root class="abc"> <xsl:copy-of select="@class" /> <xsl:attribute name="class">xyz</xsl:attribute> </root> </xsl:template> </xsl:stylesheet>""" ) ) ) result = [] def run_thread(): root = XML(_bytes('<ROOT class="ABC" />')) result.append(style(root).getroot()) self._run_thread(run_thread) self.assertEqual(_bytes('<root class="xyz"/>'), tostring(result[0]))
def test_exslt_regexp_match_groups(self): xslt = etree.XSLT( etree.XML( _bytes( """\ <xsl:stylesheet version="1.0" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <test> <xsl:for-each select="regexp:match( '123abc567', '([0-9]+)([a-z]+)([0-9]+)' )"> <test1><xsl:value-of select="."/></test1> </xsl:for-each> </test> </xsl:template> </xsl:stylesheet> """ ) ) ) result = xslt(etree.XML(_bytes("<a/>"))) root = result.getroot() self.assertEquals(root.tag, "test") self.assertEquals(len(root), 4) self.assertEquals(root[0].text, "123abc567") self.assertEquals(root[1].text, "123") self.assertEquals(root[2].text, "abc") self.assertEquals(root[3].text, "567")
def test_xslt_encoding(self): tree = self.parse(_bytes("<a><b>\\uF8D2</b><c>\\uF8D2</c></a>").decode("unicode_escape")) style = self.parse( """\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="UTF-16"/> <xsl:template match="/"> <foo><xsl:value-of select="/a/b/text()" /></foo> </xsl:template> </xsl:stylesheet>""" ) st = etree.XSLT(style) res = st(tree) expected = _bytes( """\ <?xml version="1.0" encoding="UTF-16"?> <foo>\\uF8D2</foo> """ ).decode("unicode_escape") if is_python3: self.assertEquals(expected, str(bytes(res), "UTF-16")) else: self.assertEquals(expected, unicode(str(res), "UTF-16"))
def test_multiple_elementrees(self): tree = self.parse('<a><b>B</b><c>C</c></a>') schema = etree.RelaxNG( self.parse('''\ <element name="a" xmlns="http://relaxng.org/ns/structure/1.0"> <element name="b"> <text /> </element> <element name="c"> <text /> </element> </element> ''') ) self.assert_(schema.validate(tree)) self.assert_(schema.validate(tree)) schema = etree.RelaxNG( self.parse('''\ <element name="b" xmlns="http://relaxng.org/ns/structure/1.0"> <text /> </element> ''') ) c_tree = etree.ElementTree(tree.getroot()[1]) self.assertEqual(self._rootstring(c_tree), _bytes('<c>C</c>')) self.assert_(not schema.validate(c_tree)) b_tree = etree.ElementTree(tree.getroot()[0]) self.assertEqual(self._rootstring(b_tree), _bytes('<b>B</b>')) self.assert_(schema.validate(b_tree))
def test_wide_unicode_xml(self): if sys.maxunicode < 1114111: return # skip test tree = etree.XML(_bytes('<p>\\U00026007</p>').decode('unicode_escape')) self.assertEqual(1, len(tree.text)) self.assertEqual( _bytes('\\U00026007').decode('unicode_escape'), tree.text)
def test_thread_xslt_attr_replace(self): # this is the only case in XSLT where the result tree can be # modified in-place XML = self.etree.XML tostring = self.etree.tostring style = self.etree.XSLT( XML( _bytes('''\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <root class="abc"> <xsl:copy-of select="@class" /> <xsl:attribute name="class">xyz</xsl:attribute> </root> </xsl:template> </xsl:stylesheet>'''))) result = [] def run_thread(): root = XML(_bytes('<ROOT class="ABC" />')) result.append(style(root).getroot()) self._run_thread(run_thread) self.assertEqual(_bytes('<root class="xyz"/>'), tostring(result[0]))
def test_wide_unicode_xml(self): if sys.maxunicode < 1114111: return # skip test tree = etree.XML(_bytes('<p>\\U00026007</p>').decode('unicode_escape')) self.assertEqual(1, len(tree.text)) self.assertEqual(_bytes('\\U00026007').decode('unicode_escape'), tree.text)
def test_ns_classes(self): bluff_dict = {'bluff' : self.bluff_class} maeh_dict = {'maeh' : self.maeh_class} self.Namespace('ns10').update(bluff_dict) tree = self.parse(_bytes('<bluff xmlns="ns10"><ns11:maeh xmlns:ns11="ns11"/></bluff>')) el = tree.getroot() self.assert_(isinstance(el, etree.ElementBase)) self.assert_(hasattr(el, 'bluff')) self.assertFalse(hasattr(el[0], 'maeh')) self.assertFalse(hasattr(el[0], 'bluff')) self.assertEquals(el.bluff(), 'bluff') del el self.Namespace('ns11').update(maeh_dict) el = tree.getroot() self.assert_(hasattr(el, 'bluff')) self.assert_(hasattr(el[0], 'maeh')) self.assertEquals(el.bluff(), 'bluff') self.assertEquals(el[0].maeh(), 'maeh') del el self.Namespace('ns10').clear() tree = self.parse(_bytes('<bluff xmlns="ns10"><ns11:maeh xmlns:ns11="ns11"/></bluff>')) el = tree.getroot() self.assertFalse(hasattr(el, 'bluff')) self.assertFalse(hasattr(el, 'maeh')) self.assertFalse(hasattr(el[0], 'bluff')) self.assert_(hasattr(el[0], 'maeh')) self.Namespace('ns11').clear()
def test_exslt_regexp_match1(self): # taken from http://www.exslt.org/regexp/functions/match/index.html xslt = etree.XSLT(etree.XML(_bytes("""\ <xsl:stylesheet version="1.0" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <test> <xsl:for-each select="regexp:match( 'http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml', '(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)')"> <test1><xsl:value-of select="."/></test1> </xsl:for-each> </test> </xsl:template> </xsl:stylesheet> """))) result = xslt(etree.XML(_bytes('<a/>'))) root = result.getroot() self.assertEquals(root.tag, 'test') self.assertEquals(len(root), 5) self.assertEquals( root[0].text, "http://www.bayes.co.uk/xml/index.xml?/xml/utils/rechecker.xml") self.assertEquals( root[1].text, "http") self.assertEquals( root[2].text, "www.bayes.co.uk") self.assertFalse(root[3].text) self.assertEquals( root[4].text, "/xml/index.xml?/xml/utils/rechecker.xml")
def _test_exslt_regexp_match4(self): # taken from http://www.exslt.org/regexp/functions/match/index.html # THIS IS NOT SUPPORTED! xslt = etree.XSLT(etree.XML(_bytes("""\ <xsl:stylesheet version="1.0" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <test> <xsl:for-each select="regexp:match( 'This is a test string', '([a-z])+ ', 'gi')"> <test1><xsl:value-of select="."/></test1> </xsl:for-each> </test> </xsl:template> </xsl:stylesheet> """))) result = xslt(etree.XML(_bytes('<a/>'))) root = result.getroot() self.assertEquals(root.tag, 'test') self.assertEquals(len(root), 4) self.assertEquals(root[0].text, "This") self.assertEquals(root[1].text, "is") self.assertEquals(root[2].text, "a") self.assertEquals(root[3].text, "test")
def test_xslt_encoding_override(self): tree = self.parse(_bytes('<a><b>\\uF8D2</b><c>\\uF8D2</c></a>' ).decode("unicode_escape")) style = self.parse('''\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="UTF-8"/> <xsl:template match="/"> <foo><xsl:value-of select="/a/b/text()" /></foo> </xsl:template> </xsl:stylesheet>''') st = etree.XSLT(style) res = st(tree) expected = _bytes("""\ <?xml version='1.0' encoding='UTF-16'?>\ <foo>\\uF8D2</foo>""").decode("unicode_escape") f = BytesIO() res.write(f, encoding='UTF-16') if is_python3: result = str(f.getvalue(), 'UTF-16').replace('\n', '') else: result = unicode(str(f.getvalue()), 'UTF-16').replace('\n', '') self.assertEquals(expected, result)
def test_xslt_move_result(self): root = etree.XML( _bytes( """\ <transform> <widget displayType="fieldset"/> </transform>""" ) ) xslt = etree.XSLT( etree.XML( _bytes( """\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="no"/> <xsl:template match="/"> <html> <xsl:apply-templates/> </html> </xsl:template> <xsl:template match="widget"> <xsl:element name="{@displayType}"/> </xsl:template> </xsl:stylesheet>""" ) ) ) result = xslt(root[0]) root[:] = result.getroot()[:] del root # segfaulted before
def test_thread_create_xslt(self): XML = self.etree.XML tostring = self.etree.tostring root = XML(_bytes('<a><b>B</b><c>C</c></a>')) stylesheets = [] def run_thread(): style = XML(_bytes('''\ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" /> <xsl:template match="/"> <div id="test"> <xsl:apply-templates/> </div> </xsl:template> </xsl:stylesheet>''')) stylesheets.append( etree.XSLT(style) ) self._run_thread(run_thread) st = stylesheets[0] result = tostring( st(root) ) self.assertEqual(_bytes('<div id="test">BC</div>'), result)
def test_thread_create_xslt(self): XML = self.etree.XML tostring = self.etree.tostring root = XML(_bytes("<a><b>B</b><c>C</c></a>")) stylesheets = [] def run_thread(): style = XML( _bytes( """\ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" /> <xsl:template match="/"> <div id="test"> <xsl:apply-templates/> </div> </xsl:template> </xsl:stylesheet>""" ) ) stylesheets.append(etree.XSLT(style)) self._run_thread(run_thread) st = stylesheets[0] result = tostring(st(root)) self.assertEqual(_bytes('<div id="test">BC</div>'), result)
def test_thread_mix(self): XML = self.etree.XML Element = self.etree.Element SubElement = self.etree.SubElement tostring = self.etree.tostring xml = _bytes('<a><b>B</b><c xmlns="test">C</c></a>') root = XML(xml) fragment = XML(_bytes("<other><tags/></other>")) result = self.etree.Element("{myns}root", att = "someval") def run_XML(): thread_root = XML(xml) result.append(thread_root[0]) result.append(thread_root[-1]) def run_parse(): thread_root = self.etree.parse(BytesIO(xml)).getroot() result.append(thread_root[0]) result.append(thread_root[-1]) def run_move_main(): result.append(fragment[0]) def run_build(): result.append( Element("{myns}foo", attrib={'{test}attr':'val'})) SubElement(result, "{otherns}tasty") def run_xslt(): style = XML(_bytes('''\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <foo><xsl:copy><xsl:value-of select="/a/b/text()" /></xsl:copy></foo> </xsl:template> </xsl:stylesheet>''')) st = etree.XSLT(style) result.append( st(root).getroot()[0] ) for test in (run_XML, run_parse, run_move_main, run_xslt): tostring(result) self._run_thread(test) self.assertEquals( _bytes('<ns0:root xmlns:ns0="myns" att="someval"><b>B</b><c xmlns="test">C</c><b>B</b><c xmlns="test">C</c><tags/><a>B</a></ns0:root>'), tostring(result)) def strip_first(): root = Element("newroot") root.append(result[0]) while len(result): self._run_thread(strip_first) self.assertEquals( _bytes('<ns0:root xmlns:ns0="myns" att="someval"/>'), tostring(result))
def test_boolean_attribute(self): # ability to serialize boolean attribute by setting value to None form = html.Element('form') form.set('novalidate', None) self.assertEqual(html.tostring(form), _bytes('<form novalidate></form>')) form.set('custom') self.assertEqual(html.tostring(form), _bytes('<form novalidate custom></form>'))
def test_xpath_list_unicode_text_parent(self): xml = _bytes('<a><b>FooBar\\u0680\\u3120</b><b>BarFoo\\u0680\\u3120</b></a>').decode("unicode_escape") tree = self.parse(xml.encode('utf-8')) root = tree.getroot() self.assertEquals([_bytes('FooBar\\u0680\\u3120').decode("unicode_escape"), _bytes('BarFoo\\u0680\\u3120').decode("unicode_escape")], tree.xpath('/a/b/text()')) self.assertEquals([root[0], root[1]], [r.getparent() for r in tree.xpath('/a/b/text()')])
def test_wide_unicode_xml(self): if sys.maxunicode < 1114111: return # skip test element = self.etree.HTML(_bytes( '<html><body><p>\\U00026007</p></body></html>' ).decode('unicode_escape')) p_text = element.findtext('.//p') self.assertEqual(1, len(p_text)) self.assertEqual(_bytes('\\U00026007').decode('unicode_escape'), p_text)
def test_element_sax(self): tree = self.parse("<a><b/></a>") a = tree.getroot() b = a[0] xml_out = self._saxify_serialize(a) self.assertEqual(_bytes("<a><b/></a>"), xml_out) xml_out = self._saxify_serialize(b) self.assertEqual(_bytes("<b/>"), xml_out)
def test_element_sax(self): tree = self.parse('<a><b/></a>') a = tree.getroot() b = a[0] xml_out = self._saxify_serialize(a) self.assertEqual(_bytes('<a><b/></a>'), xml_out) xml_out = self._saxify_serialize(b) self.assertEqual(_bytes('<b/>'), xml_out)
def test_wide_unicode_xml(self): if sys.maxunicode < 1114111: return # skip test element = self.etree.HTML( _bytes('<html><body><p>\\U00026007</p></body></html>').decode( 'unicode_escape')) p_text = element.findtext('.//p') self.assertEqual(1, len(p_text)) self.assertEqual( _bytes('\\U00026007').decode('unicode_escape'), p_text)
def test_multiple_elementrees(self): tree = self.parse('<a><b>B</b><c>C</c></a>') style = self.parse('''\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="a"><A><xsl:apply-templates/></A></xsl:template> <xsl:template match="b"><B><xsl:apply-templates/></B></xsl:template> <xsl:template match="c"><C><xsl:apply-templates/></C></xsl:template> </xsl:stylesheet>''') self.assertEquals(self._rootstring(tree), _bytes('<a><b>B</b><c>C</c></a>')) result = tree.xslt(style) self.assertEquals(self._rootstring(tree), _bytes('<a><b>B</b><c>C</c></a>')) self.assertEquals(self._rootstring(result), _bytes('<A><B>B</B><C>C</C></A>')) b_tree = etree.ElementTree(tree.getroot()[0]) self.assertEquals(self._rootstring(b_tree), _bytes('<b>B</b>')) result = b_tree.xslt(style) self.assertEquals(self._rootstring(tree), _bytes('<a><b>B</b><c>C</c></a>')) self.assertEquals(self._rootstring(result), _bytes('<B>B</B>')) c_tree = etree.ElementTree(tree.getroot()[1]) self.assertEquals(self._rootstring(c_tree), _bytes('<c>C</c>')) result = c_tree.xslt(style) self.assertEquals(self._rootstring(tree), _bytes('<a><b>B</b><c>C</c></a>')) self.assertEquals(self._rootstring(result), _bytes('<C>C</C>'))
def test_write_filename(self): # (c)ElementTree supports filename strings as write argument handle, filename = tempfile.mkstemp(suffix=".xml") self.tree.write(filename) try: self.assertEqual(read_file(filename, 'rb').replace(_bytes('\n'), _bytes('')), self.root_str) finally: os.close(handle) os.remove(filename)
def test_subtree_copy_thread(self): tostring = self.etree.tostring XML = self.etree.XML xml = _bytes("<root><threadtag/></root>") main_root = XML(_bytes("<root/>")) def run_thread(): thread_root = XML(xml) main_root.append(thread_root[0]) del thread_root self._run_thread(run_thread) self.assertEqual(xml, tostring(main_root))
def _test_xpath_compile_unicode(self): x = self.parse(_bytes('<a><b xmlns="http://nsa/\\uf8d2"/><b xmlns="http://nsb/\\uf8d1"/></a>' ).decode("unicode_escape")) expr = etree.ETXPath(_bytes("/a/{http://nsa/\\uf8d2}b").decode("unicode_escape")) r = expr(x) self.assertEquals(1, len(r)) self.assertEquals(_bytes('{http://nsa/\\uf8d2}b').decode("unicode_escape"), r[0].tag) expr = etree.ETXPath(_bytes("/a/{http://nsb/\\uf8d1}b").decode("unicode_escape")) r = expr(x) self.assertEquals(1, len(r)) self.assertEquals(_bytes('{http://nsb/\\uf8d1}b').decode("unicode_escape"), r[0].tag)
def test_dtd_invalid_duplicate_id(self): root = etree.XML(_bytes(''' <a><b id="id1"/><b id="id2"/><b id="id1"/></a> ''')) dtd = etree.DTD(BytesIO(_bytes(""" <!ELEMENT a (b*)> <!ATTLIST b id ID #REQUIRED > <!ELEMENT b EMPTY> """))) self.assertFalse(dtd.validate(root)) self.assertTrue(dtd.error_log) self.assertTrue([error for error in dtd.error_log if 'id1' in error.message])
def test_default_class_lookup(self): class TestElement(etree.ElementBase): FIND_ME = "default element" class TestComment(etree.CommentBase): FIND_ME = "default comment" class TestPI(etree.PIBase): FIND_ME = "default pi" parser = etree.XMLParser() lookup = etree.ElementDefaultClassLookup(element=TestElement, comment=TestComment, pi=TestPI) parser.set_element_class_lookup(lookup) root = etree.XML( _bytes("""<?xml version='1.0'?> <root> <?myPI?> <!-- hi --> </root> """), parser) self.assertEqual("default element", root.FIND_ME) self.assertEqual("default pi", root[0].FIND_ME) self.assertEqual("default comment", root[1].FIND_ME)
def test_concurrent_class_lookup(self): XML = self.etree.XML class TestElement(etree.ElementBase): pass class MyLookup(etree.CustomElementClassLookup): repeat = range(100) def lookup(self, t, d, ns, name): count = 0 for i in self.repeat: # allow other threads to run count += 1 return TestElement parser = self.etree.XMLParser() parser.set_element_class_lookup(MyLookup()) root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b><c/></root>'), parser) child_count = len(root) def testrun(): for i in range(1000): el = root[i % child_count] del el threads = [threading.Thread(target=testrun) for _ in range(10)] for thread in threads: thread.start() for thread in threads: thread.join()
def test_class_lookup_reentry(self): XML = self.etree.XML class TestElement(etree.ElementBase): FIND_ME = "here" root = None class MyLookup(etree.CustomElementClassLookup): el = None def lookup(self, t, d, ns, name): if root is not None: # not in the parser if self.el is None and name == "a": self.el = [] self.el.append(root.find(name)) return TestElement parser = self.etree.XMLParser() parser.set_element_class_lookup(MyLookup()) root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b></root>'), parser) a = root[0] self.assertEquals(a.tag, "a") self.assertEquals(root[0].tag, "a") del a self.assertEquals(root[0].tag, "a")
def test_module_HTML_unicode(self): element = self.etree.HTML(self.uhtml_str) self.assertEqual( self.etree.tostring(element, method="html", encoding='unicode'), self.uhtml_str) self.assertEqual(element.findtext('.//h1'), _bytes("page á title").decode('utf8'))
def test_extension_element(self): tree = self.parse("<a><b>B</b></a>") style = self.parse( """\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:myns="testns" extension-element-prefixes="myns" exclude-result-prefixes="myns"> <xsl:template match="a"> <A><myns:myext>b</myns:myext></A> </xsl:template> </xsl:stylesheet>""" ) class MyExt(etree.XSLTExtension): def execute(self, context, self_node, input_node, output_parent): child = etree.Element(self_node.text) child.text = "X" output_parent.append(child) extensions = {("testns", "myext"): MyExt()} result = tree.xslt(style, extensions=extensions) self.assertEquals(self._rootstring(result), _bytes("<A><b>X</b></A>"))
def test_exslt_regexp_match2(self): # taken from http://www.exslt.org/regexp/functions/match/index.html xslt = etree.XSLT( self.parse( """\ <xsl:stylesheet version="1.0" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <test> <xsl:for-each select="regexp:match( 'This is a test string', '(\w+)', 'g')"> <test1><xsl:value-of select="."/></test1> </xsl:for-each> </test> </xsl:template> </xsl:stylesheet> """ ) ) result = xslt(etree.XML(_bytes("<a/>"))) root = result.getroot() self.assertEquals(root.tag, "test") self.assertEquals(len(root), 5) self.assertEquals(root[0].text, "This") self.assertEquals(root[1].text, "is") self.assertEquals(root[2].text, "a") self.assertEquals(root[3].text, "test") self.assertEquals(root[4].text, "string")
def test_xslt_document_XML_resolver(self): # make sure document('') works when custom resolvers are in use assertEquals = self.assertEquals called = {"count": 0} class TestResolver(etree.Resolver): def resolve(self, url, id, context): assertEquals(url, "file://ANYTHING") called["count"] += 1 return self.resolve_string("<CALLED/>", context) parser = etree.XMLParser() parser.resolvers.add(TestResolver()) xslt = etree.XSLT( etree.XML( _bytes( """\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:l="local"> <xsl:template match="/"> <test> <xsl:for-each select="document('')//l:data/l:entry"> <xsl:copy-of select="document('file://ANYTHING')"/> <xsl:copy> <xsl:attribute name="value"> <xsl:value-of select="."/> </xsl:attribute> </xsl:copy> </xsl:for-each> </test> </xsl:template> <l:data> <l:entry>A</l:entry> <l:entry>B</l:entry> </l:data> </xsl:stylesheet> """ ), parser, ) ) self.assertEquals(called["count"], 0) result = xslt(etree.XML("<a/>")) self.assertEquals(called["count"], 1) root = result.getroot() self.assertEquals(root.tag, "test") self.assertEquals(len(root), 4) self.assertEquals(root[0].tag, "CALLED") self.assertEquals(root[1].tag, "{local}entry") self.assertEquals(root[1].text, None) self.assertEquals(root[1].get("value"), "A") self.assertEquals(root[2].tag, "CALLED") self.assertEquals(root[3].tag, "{local}entry") self.assertEquals(root[3].text, None) self.assertEquals(root[3].get("value"), "B")
def test_main_xslt_in_thread(self): XML = self.etree.XML style = XML( _bytes( """\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <foo><xsl:copy><xsl:value-of select="/a/b/text()" /></xsl:copy></foo> </xsl:template> </xsl:stylesheet>""" ) ) st = etree.XSLT(style) result = [] def run_thread(): root = XML(_bytes("<a><b>B</b><c>C</c></a>")) result.append(st(root)) self._run_thread(run_thread) self.assertEqual( """\ <?xml version="1.0"?> <foo><a>B</a></foo> """, str(result[0]), )
def test_dtd_parse_invalid(self): fromstring = etree.fromstring parser = etree.XMLParser(dtd_validation=True) xml = _bytes('<!DOCTYPE b SYSTEM "%s"><b><a/></b>' % fileInTestDir("test.dtd")) self.assertRaises(etree.XMLSyntaxError, fromstring, xml, parser=parser)
def test_default_tagname(self): bluff_dict = {None: self.bluff_class, 'maeh': self.maeh_class} ns = self.Namespace("uri:nsDefClass") ns.update(bluff_dict) tree = self.parse( _bytes(''' <test xmlns="bla" xmlns:ns1="uri:nsDefClass" xmlns:ns2="uri:nsDefClass"> <ns2:el1/><ns1:el2/><ns1:maeh/><ns2:maeh/><maeh/> </test> ''')) el = tree.getroot() self.assertFalse(isinstance(el, etree.ElementBase)) for child in el[:-1]: self.assertTrue(isinstance(child, etree.ElementBase), child.tag) self.assertFalse(isinstance(el[-1], etree.ElementBase)) self.assertTrue(hasattr(el[0], 'bluff')) self.assertTrue(hasattr(el[1], 'bluff')) self.assertTrue(hasattr(el[2], 'maeh')) self.assertTrue(hasattr(el[3], 'maeh')) self.assertFalse(hasattr(el[4], 'maeh')) del el ns.clear()
def test_class_lookup_reentry(self): XML = self.etree.XML class TestElement(etree.ElementBase): FIND_ME = "here" root = None class MyLookup(etree.CustomElementClassLookup): el = None def lookup(self, t, d, ns, name): if root is not None: # not in the parser if self.el is None and name == "a": self.el = [] self.el.append(root.find(name)) return TestElement parser = self.etree.XMLParser() parser.set_element_class_lookup(MyLookup()) root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b></root>'), parser) a = root[0] self.assertEqual(a.tag, "a") self.assertEqual(root[0].tag, "a") del a self.assertEqual(root[0].tag, "a")
def test_concurrent_class_lookup(self): XML = self.etree.XML class TestElement(etree.ElementBase): pass class MyLookup(etree.CustomElementClassLookup): repeat = range(100) def lookup(self, t, d, ns, name): count = 0 for i in self.repeat: # allow other threads to run count += 1 return TestElement parser = self.etree.XMLParser() parser.set_element_class_lookup(MyLookup()) root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b><c/></root>'), parser) child_count = len(root) def testrun(): for i in range(1000): el = root[i%child_count] del el self._run_threads(10, testrun)
def test_extension_element_apply_templates(self): tree = self.parse('<a><b>B</b></a>') style = self.parse('''\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:myns="testns" extension-element-prefixes="myns"> <xsl:template match="a"> <A><myns:myext><x>X</x><y>Y</y><z/></myns:myext></A> </xsl:template> <xsl:template match="x" /> <xsl:template match="z">XYZ</xsl:template> </xsl:stylesheet>''') class MyExt(etree.XSLTExtension): def execute(self, context, self_node, input_node, output_parent): for child in self_node: for result in self.apply_templates(context, child): if isinstance(result, basestring): el = etree.Element("T") el.text = result else: el = result output_parent.append(el) extensions = { ('testns', 'myext') : MyExt() } result = tree.xslt(style, extensions=extensions) self.assertEquals(self._rootstring(result), _bytes('<A><T>Y</T><T>XYZ</T></A>'))
def test_variable_result_tree_fragment(self): tree = self.parse('<a><b>B</b><b/></a>') style = self.parse('''\ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:myns="testns" exclude-result-prefixes="myns"> <xsl:template match="a"> <xsl:variable name="content"> <xsl:apply-templates/> </xsl:variable> <A><xsl:value-of select="myns:mytext($content)"/></A> </xsl:template> <xsl:template match="b"><xsl:copy>BBB</xsl:copy></xsl:template> </xsl:stylesheet>''') def mytext(ctxt, values): for value in values: self.assert_(hasattr(value, 'tag'), "%s is not an Element" % type(value)) self.assertEquals(value.tag, 'b') self.assertEquals(value.text, 'BBB') return 'X'.join([el.tag for el in values]) namespace = etree.FunctionNamespace('testns') namespace['mytext'] = mytext result = tree.xslt(style) self.assertEquals(self._rootstring(result), _bytes('<A>bXb</A>'))
def test_set_decl_public(self): doc = etree.Element('test').getroottree() doc.docinfo.public_id = 'bar' doc.docinfo.system_url = 'baz' self.assertEqual(doc.docinfo.doctype, '<!DOCTYPE test PUBLIC "bar" "baz">') self.assertEqual(etree.tostring(doc), _bytes('<!DOCTYPE test PUBLIC "bar" "baz">\n<test/>'))
def test_ietf_decl(self): html_data = ('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">\n' '<html></html>') root = etree.HTML(html_data) doc = root.getroottree() self.assertEqual(doc.docinfo.doctype, '<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN">') self.assertEqual(etree.tostring(doc, method='html'), _bytes(html_data))
def test_ns_classes(self): bluff_dict = {'bluff': self.bluff_class} maeh_dict = {'maeh': self.maeh_class} self.Namespace('ns10').update(bluff_dict) tree = self.parse( _bytes( '<bluff xmlns="ns10"><ns11:maeh xmlns:ns11="ns11"/></bluff>')) el = tree.getroot() self.assertTrue(isinstance(el, etree.ElementBase)) self.assertTrue(hasattr(el, 'bluff')) self.assertFalse(hasattr(el[0], 'maeh')) self.assertFalse(hasattr(el[0], 'bluff')) self.assertEqual(el.bluff(), 'bluff') del el # This is needed in pypy, to clear the object proxies import gc gc.collect() self.Namespace('ns11').update(maeh_dict) tree = self.parse( _bytes( '<bluff xmlns="ns10"><ns11:maeh xmlns:ns11="ns11"/></bluff>')) el = tree.getroot() self.assertTrue(hasattr(el, 'bluff')) self.assertTrue(hasattr(el[0], 'maeh')) self.assertEqual(el.bluff(), 'bluff') self.assertEqual(el[0].maeh(), 'maeh') del el self.Namespace('ns10').clear() tree = self.parse( _bytes( '<bluff xmlns="ns10"><ns11:maeh xmlns:ns11="ns11"/></bluff>')) el = tree.getroot() self.assertFalse(hasattr(el, 'bluff')) self.assertFalse(hasattr(el, 'maeh')) self.assertFalse(hasattr(el[0], 'bluff')) self.assertTrue(hasattr(el[0], 'maeh')) self.Namespace('ns11').clear()
def test_unicode_text(self): e = etree.Element('e') def settext(text): e.text = text self.assertRaises(ValueError, settext, _str('ab\ufffe')) self.assertRaises(ValueError, settext, _str('ö\ffff')) self.assertRaises(ValueError, settext, _str('\u0123\ud800')) self.assertRaises(ValueError, settext, _str('x\ud8ff')) self.assertRaises(ValueError, settext, _str('\U00010000\udfff')) self.assertRaises(ValueError, settext, _str('abd\x00def')) # should not Raise settext(_str('\ud7ff\ue000\U00010000\U0010FFFFäöas')) for char_val in range(0xD800, 0xDFFF + 1): self.assertRaises(ValueError, settext, 'abc' + _chr(char_val)) self.assertRaises(ValueError, settext, _chr(char_val)) self.assertRaises(ValueError, settext, _chr(char_val) + 'abc') self.assertRaises(ValueError, settext, _bytes('\xe4')) self.assertRaises(ValueError, settext, _bytes('\x80')) self.assertRaises(ValueError, settext, _bytes('\xff')) self.assertRaises(ValueError, settext, _bytes('\x08')) self.assertRaises(ValueError, settext, _bytes('\x19')) self.assertRaises(ValueError, settext, _bytes('\x20\x00')) # should not Raise settext(_bytes('\x09\x0A\x0D\x20\x60\x7f'))