""" On-device verification for the cross-compiled lxml wheel (norelro). Run after installing: pip install lxml-6.1.1-cp312-cp312-android_24_x86_64.whl Usage: python Test_lxml.py Exit code 0 = everything required PASSed. Generated by RIMI """ import sys RESULTS = [] def test(name, fn): try: fn() RESULTS.append((name, "PASS", None)) except Exception as exc: RESULTS.append((name, "FAIL", "%s: %s" % (type(exc).__name__, exc))) print(" ! %s -> %s: %s" % (name, type(exc).__name__, exc)) def section(title): print("=" * 60) print(title) print("=" * 60) # --------------------------------------------------------------------------- # 1. import / version # --------------------------------------------------------------------------- def import_lxml(): import lxml.etree as etree print(" lxml.etree version", etree.LXML_VERSION) print(" libxml2", etree.LIBXML_VERSION) print(" libxslt", etree.LIBXSLT_VERSION) def import_objectify(): from lxml import objectify print(" lxml.objectify OK") def import_html(): from lxml import html print(" lxml.html OK") def import_html_clean(): from lxml_html_clean import clean print(" lxml_html_clean OK") # --------------------------------------------------------------------------- # 2. etree basics # --------------------------------------------------------------------------- def parse_string(): from lxml import etree xml = b"helloworld" root = etree.fromstring(xml) assert root.tag == "root" items = root.findall("item") assert len(items) == 2 assert items[0].get("id") == "1" assert items[0].text == "hello" def parse_file(): from lxml import etree xml = b"12" root = etree.fromstring(xml) row = root.find("row") assert int(row.find("a").text) == 1 assert int(row.find("b").text) == 2 def tostring(): from lxml import etree root = etree.Element("parent") child = etree.SubElement(root, "child") child.text = "text" s = etree.tostring(root, encoding="unicode") assert "text" in s def xpath(): from lxml import etree xml = b"" root = etree.fromstring(xml) a_list = root.xpath("//a") assert len(a_list) == 2 vals = root.xpath("//a/@x") assert vals == ["1", "2"] first = root.xpath("//a[@x='2']") assert len(first) == 1 def namespaces(): from lxml import etree ns = {"s": "http://example.com/ns"} xml = b'ok' root = etree.fromstring(xml) items = root.xpath("//s:item", namespaces=ns) assert len(items) == 1 assert items[0].text == "ok" # --------------------------------------------------------------------------- # 3. build / modify trees # --------------------------------------------------------------------------- def build_tree(): from lxml import etree root = etree.Element("root") for i in range(5): child = etree.SubElement(root, "item") child.set("index", str(i)) child.text = "val_%d" % i assert len(root) == 5 assert root[2].get("index") == "2" assert root[4].text == "val_4" def modify_tree(): from lxml import etree root = etree.Element("root") a = etree.SubElement(root, "a") b = etree.SubElement(root, "b") root.remove(b) assert len(root) == 1 a.text = "modified" assert root[0].text == "modified" # --------------------------------------------------------------------------- # 4. HTML parsing # --------------------------------------------------------------------------- def html_parse(): from lxml import html doc = html.fromstring("

Hello

World

") ps = doc.xpath("//p") assert len(ps) == 2 assert ps[0].text == "Hello" def html_tostring(): from lxml import html doc = html.fromstring("
content
") s = html.tostring(doc, encoding="unicode") assert "content" in s assert 'id="main"' in s # --------------------------------------------------------------------------- # 5. html_clean (bundled dep) # --------------------------------------------------------------------------- def html_clean(): from lxml_html_clean import Cleaner from lxml import html dirty = '

safe

' doc = html.fromstring(dirty) c = Cleaner() c.clean_html(doc) s = html.tostring(doc, encoding="unicode") assert "safe" in s # --------------------------------------------------------------------------- # 6. XSLT # --------------------------------------------------------------------------- def xslt_transform(): from lxml import etree xml = b"12" xslt_str = b""" """ xml_doc = etree.fromstring(xml) xslt_doc = etree.fromstring(xslt_str) transform = etree.XSLT(xslt_doc) result = transform(xml_doc) s = etree.tostring(result, encoding="unicode") assert "1" in s assert "2" in s # --------------------------------------------------------------------------- # 7. XML schema validation # --------------------------------------------------------------------------- def schema_validate(): from lxml import etree schema_xml = b""" """ schema_doc = etree.fromstring(schema_xml) schema = etree.XMLSchema(schema_doc) valid = etree.fromstring(b"Alice30") assert schema.validate(valid) invalid = etree.fromstring(b"Alice") assert not schema.validate(invalid) # --------------------------------------------------------------------------- # 8. c14n (canonicalization) # --------------------------------------------------------------------------- def c14n(): from lxml import etree xml = b'text' root = etree.fromstring(xml) c = etree.tostring(root, method="c14n") assert b'attr="1"' in c assert b"" in c # --------------------------------------------------------------------------- def main(): section("1. import / version") test("import lxml.etree", import_lxml) test("import lxml.objectify", import_objectify) test("import lxml.html", import_html) test("import lxml_html_clean", import_html_clean) section("2. etree basics") test("parse fromstring", parse_string) test("parse file-like", parse_file) test("tostring", tostring) test("xpath", xpath) test("namespaces", namespaces) section("3. build / modify trees") test("build tree", build_tree) test("modify tree", modify_tree) section("4. HTML parsing") test("html parse", html_parse) test("html tostring", html_tostring) section("5. html_clean (bundled dep)") test("clean HTML", html_clean) section("6. XSLT") test("xslt transform", xslt_transform) section("7. XML schema validation") test("schema validate", schema_validate) section("8. c14n") test("canonicalization", c14n) print() print("=" * 60) print("SUMMARY") print("=" * 60) fails = 0 for name, status, why in RESULTS: mark = " OK" if status == "PASS" else "FAIL" print("%s %s" % (mark, name)) if why: print(" -> %s" % why) if status == "FAIL": fails += 1 print() passed = len(RESULTS) - fails print("passed=%d failed=%d" % (passed, fails)) if fails: print("RESULT: FAILED") else: print("RESULT: PASSED") sys.exit(1 if fails else 0) if __name__ == "__main__": main()