1
2
3 """
4 Tests specific to the lxml.objectify API
5 """
6
7 from __future__ import absolute_import
8
9 import unittest, operator
10
11 from .common_imports import (
12 etree, HelperTestCase, fileInTestDir, doctest, make_doctest, _bytes, _str, BytesIO
13 )
14
15 from lxml import objectify
16
17 PYTYPE_NAMESPACE = "http://codespeak.net/lxml/objectify/pytype"
18 XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
19 XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
20 XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
21 XML_SCHEMA_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
22 TREE_PYTYPE = "TREE"
23 DEFAULT_NSMAP = { "py" : PYTYPE_NAMESPACE,
24 "xsi" : XML_SCHEMA_INSTANCE_NS,
25 "xsd" : XML_SCHEMA_NS}
26
27 objectclass2xsitype = {
28
29 objectify.IntElement: ("int", "short", "byte", "unsignedShort",
30 "unsignedByte", "integer", "nonPositiveInteger",
31 "negativeInteger", "long", "nonNegativeInteger",
32 "unsignedLong", "unsignedInt", "positiveInteger",),
33 objectify.FloatElement: ("float", "double"),
34 objectify.BoolElement: ("boolean",),
35 objectify.StringElement: ("string", "normalizedString", "token", "language",
36 "Name", "NCName", "ID", "IDREF", "ENTITY",
37 "NMTOKEN", ),
38
39 }
40
41 xsitype2objclass = dict([ (v, k) for k in objectclass2xsitype
42 for v in objectclass2xsitype[k] ])
43
44 objectclass2pytype = {
45
46 objectify.IntElement: "int",
47 objectify.FloatElement: "float",
48 objectify.BoolElement: "bool",
49 objectify.StringElement: "str",
50
51 }
52
53 pytype2objclass = dict([ (objectclass2pytype[k], k)
54 for k in objectclass2pytype])
55
56 xml_str = '''\
57 <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
58 <obj:c1 a1="A1" a2="A2" other:a3="A3">
59 <obj:c2>0</obj:c2>
60 <obj:c2>1</obj:c2>
61 <obj:c2>2</obj:c2>
62 <other:c2>3</other:c2>
63 <c2>4</c2>
64 </obj:c1>
65 </obj:root>'''
66
68 """Test cases for lxml.objectify
69 """
70 etree = etree
71
74
88
102
103
107
112
119
129
134
140
148
159
163
168
175
185
190
196
204
215
217
218 value = objectify.ObjectifiedDataElement('test', 'toast')
219 self.assertEqual(value.text, 'testtoast')
220
225
227
228 value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
229 attrib={"gnu": "muh", "cat": "meeow",
230 "dog": "wuff"},
231 bird="tchilp", dog="grrr")
232 self.assertEqual(value.get("gnu"), "muh")
233 self.assertEqual(value.get("cat"), "meeow")
234 self.assertEqual(value.get("dog"), "grrr")
235 self.assertEqual(value.get("bird"), "tchilp")
236
248
250
251
252 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
253 attrib={"gnu": "muh", "cat": "meeow",
254 "dog": "wuff"},
255 bird="tchilp", dog="grrr")
256 value = objectify.DataElement(arg, _pytype="NoneType")
257 self.assertTrue(isinstance(value, objectify.NoneElement))
258 self.assertEqual(value.get(XML_SCHEMA_NIL_ATTR), "true")
259 self.assertEqual(value.text, None)
260 self.assertEqual(value.pyval, None)
261 for attr in arg.attrib:
262
263 self.assertEqual(value.get(attr), arg.get(attr))
264
266
267
268 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
269 attrib={"gnu": "muh", "cat": "meeow",
270 "dog": "wuff"},
271 bird="tchilp", dog="grrr")
272 value = objectify.DataElement(arg, _pytype="int")
273 self.assertTrue(isinstance(value, objectify.IntElement))
274 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
275 for attr in arg.attrib:
276 if not attr == objectify.PYTYPE_ATTRIBUTE:
277 self.assertEqual(value.get(attr), arg.get(attr))
278
280
281
282 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
283 attrib={"gnu": "muh", "cat": "meeow",
284 "dog": "wuff"},
285 bird="tchilp", dog="grrr")
286 value = objectify.DataElement(arg, _xsi="xsd:int")
287 self.assertTrue(isinstance(value, objectify.IntElement))
288 self.assertEqual(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
289 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
290 for attr in arg.attrib:
291 if not attr in [objectify.PYTYPE_ATTRIBUTE,
292 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
293 self.assertEqual(value.get(attr), arg.get(attr))
294
296
297
298 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
299 attrib={"gnu": "muh", "cat": "meeow",
300 "dog": "wuff"},
301 bird="tchilp", dog="grrr")
302 value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
303 self.assertTrue(isinstance(value, objectify.IntElement))
304 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
305 self.assertEqual(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
306 for attr in arg.attrib:
307 if not attr in [objectify.PYTYPE_ATTRIBUTE,
308 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
309 self.assertEqual(value.get(attr), arg.get(attr))
310
314
318
323
328
335
339
343
347
349 root = self.XML("""
350 <root>
351 <foo:x xmlns:foo="/foo/bar">1</foo:x>
352 <x>2</x>
353 </root>
354 """)
355 self.assertEqual(2, root.x)
356
361
363 root = self.XML(xml_str)
364 self.assertEqual("0", getattr(root.c1, "{objectified}c2").text)
365 self.assertEqual("3", getattr(root.c1, "{otherNS}c2").text)
366
368 root = self.XML(xml_str)
369 self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
370 self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
371
376
378 for val in [
379 2, 2**32, 1.2, "Won't get fooled again",
380 _str("W\xf6n't get f\xf6\xf6led \xe4g\xe4in", 'ISO-8859-1'), True,
381 False, None]:
382 root = self.Element('root')
383 attrname = 'val'
384 setattr(root, attrname, val)
385 result = getattr(root, attrname)
386 self.assertEqual(val, result)
387 self.assertEqual(type(val), type(result.pyval))
388
395
402
404 root = self.XML(xml_str)
405 self.assertEqual(1, len(root.c1))
406
407 new_el = self.Element("test", myattr="5")
408 root.addattr("c1", new_el)
409 self.assertEqual(2, len(root.c1))
410 self.assertEqual(None, root.c1[0].get("myattr"))
411 self.assertEqual("5", root.c1[1].get("myattr"))
412
414 root = self.XML(xml_str)
415 self.assertEqual(1, len(root.c1))
416
417 new_el = self.Element("test")
418 self.etree.SubElement(new_el, "a", myattr="A")
419 self.etree.SubElement(new_el, "a", myattr="B")
420
421 root.addattr("c1", list(new_el.a))
422 self.assertEqual(3, len(root.c1))
423 self.assertEqual(None, root.c1[0].get("myattr"))
424 self.assertEqual("A", root.c1[1].get("myattr"))
425 self.assertEqual("B", root.c1[2].get("myattr"))
426
433
435 root = self.XML(xml_str)
436 self.assertEqual("0", root.c1.c2[0].text)
437 self.assertEqual("1", root.c1.c2[1].text)
438 self.assertEqual("2", root.c1.c2[2].text)
439 self.assertRaises(IndexError, operator.getitem, root.c1.c2, 3)
440 self.assertEqual(root, root[0])
441 self.assertRaises(IndexError, operator.getitem, root, 1)
442
443 c1 = root.c1
444 del root.c1
445 self.assertEqual(c1, c1[0])
446 self.assertRaises(IndexError, operator.getitem, c1, 1)
447
449 root = self.XML(xml_str)
450 self.assertEqual("0", root.c1.c2[0].text)
451 self.assertEqual("0", root.c1.c2[-3].text)
452 self.assertEqual("1", root.c1.c2[-2].text)
453 self.assertEqual("2", root.c1.c2[-1].text)
454 self.assertRaises(IndexError, operator.getitem, root.c1.c2, -4)
455 self.assertEqual(root, root[-1])
456 self.assertRaises(IndexError, operator.getitem, root, -2)
457
458 c1 = root.c1
459 del root.c1
460 self.assertEqual(c1, c1[-1])
461 self.assertRaises(IndexError, operator.getitem, c1, -2)
462
464 root = self.XML(xml_str)
465 self.assertEqual(1, len(root))
466 self.assertEqual(1, len(root.c1))
467 self.assertEqual(3, len(root.c1.c2))
468
477
483
493
498
503
504
505
507 root = self.XML("<root><c>c1</c><c>c2</c></root>")
508 self.assertEqual(["c1", "c2"],
509 [ c.text for c in root.c[:] ])
510
512 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
513 test_list = ["c1", "c2", "c3", "c4"]
514
515 self.assertEqual(test_list,
516 [ c.text for c in root.c[:] ])
517 self.assertEqual(test_list[1:2],
518 [ c.text for c in root.c[1:2] ])
519 self.assertEqual(test_list[-3:-1],
520 [ c.text for c in root.c[-3:-1] ])
521 self.assertEqual(test_list[-3:3],
522 [ c.text for c in root.c[-3:3] ])
523 self.assertEqual(test_list[-3000:3],
524 [ c.text for c in root.c[-3000:3] ])
525 self.assertEqual(test_list[-3:3000],
526 [ c.text for c in root.c[-3:3000] ])
527
529 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
530 test_list = ["c1", "c2", "c3", "c4"]
531
532 self.assertEqual(test_list,
533 [ c.text for c in root.c[:] ])
534 self.assertEqual(test_list[2:1:-1],
535 [ c.text for c in root.c[2:1:-1] ])
536 self.assertEqual(test_list[-1:-3:-1],
537 [ c.text for c in root.c[-1:-3:-1] ])
538 self.assertEqual(test_list[2:-3:-1],
539 [ c.text for c in root.c[2:-3:-1] ])
540 self.assertEqual(test_list[2:-3000:-1],
541 [ c.text for c in root.c[2:-3000:-1] ])
542
543
544
556
558 Element = self.Element
559 root = Element("root")
560 root.c = ["c1", "c2"]
561
562 c1 = root.c[0]
563 c2 = root.c[1]
564
565 self.assertEqual([c1,c2], list(root.c))
566 self.assertEqual(["c1", "c2"],
567 [ c.text for c in root.c ])
568
569 root2 = Element("root2")
570 root2.el = [ "test", "test" ]
571 self.assertEqual(["test", "test"],
572 [ el.text for el in root2.el ])
573
574 root.c = [ root2.el, root2.el ]
575 self.assertEqual(["test", "test"],
576 [ c.text for c in root.c ])
577 self.assertEqual(["test", "test"],
578 [ el.text for el in root2.el ])
579
580 root.c[:] = [ c1, c2, c2, c1 ]
581 self.assertEqual(["c1", "c2", "c2", "c1"],
582 [ c.text for c in root.c ])
583
585 Element = self.Element
586 root = Element("root")
587 l = ["c1", "c2", "c3", "c4"]
588 root.c = l
589
590 self.assertEqual(["c1", "c2", "c3", "c4"],
591 [ c.text for c in root.c ])
592 self.assertEqual(l,
593 [ c.text for c in root.c ])
594
595 new_slice = ["cA", "cB"]
596 l[1:2] = new_slice
597 root.c[1:2] = new_slice
598
599 self.assertEqual(["c1", "cA", "cB", "c3", "c4"], l)
600 self.assertEqual(["c1", "cA", "cB", "c3", "c4"],
601 [ c.text for c in root.c ])
602 self.assertEqual(l,
603 [ c.text for c in root.c ])
604
606 Element = self.Element
607 root = Element("root")
608 l = ["c1", "c2", "c3", "c4"]
609 root.c = l
610
611 self.assertEqual(["c1", "c2", "c3", "c4"],
612 [ c.text for c in root.c ])
613 self.assertEqual(l,
614 [ c.text for c in root.c ])
615
616 new_slice = ["cA", "cB"]
617 l[1:1] = new_slice
618 root.c[1:1] = new_slice
619
620 self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"], l)
621 self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"],
622 [ c.text for c in root.c ])
623 self.assertEqual(l,
624 [ c.text for c in root.c ])
625
627 Element = self.Element
628 root = Element("root")
629 l = ["c1", "c2", "c3", "c4"]
630 root.c = l
631
632 self.assertEqual(["c1", "c2", "c3", "c4"],
633 [ c.text for c in root.c ])
634 self.assertEqual(l,
635 [ c.text for c in root.c ])
636
637 new_slice = ["cA", "cB"]
638 l[-2:-2] = new_slice
639 root.c[-2:-2] = new_slice
640
641 self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"], l)
642 self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"],
643 [ c.text for c in root.c ])
644 self.assertEqual(l,
645 [ c.text for c in root.c ])
646
654
656 Element = self.Element
657 root = Element("root")
658 l = ["c1", "c2", "c3", "c4"]
659 root.c = l
660
661 self.assertEqual(["c1", "c2", "c3", "c4"],
662 [ c.text for c in root.c ])
663 self.assertEqual(l,
664 [ c.text for c in root.c ])
665
666 new_slice = ["cA", "cB", "cC"]
667 self.assertRaises(
668 ValueError, operator.setitem,
669 l, slice(1,2,-1), new_slice)
670 self.assertRaises(
671 ValueError, operator.setitem,
672 root.c, slice(1,2,-1), new_slice)
673
675 Element = self.Element
676 root = Element("root")
677 l = ["c1", "c2", "c3", "c4"]
678 root.c = l
679
680 self.assertEqual(["c1", "c2", "c3", "c4"],
681 [ c.text for c in root.c ])
682 self.assertEqual(l,
683 [ c.text for c in root.c ])
684
685 new_slice = ["cA", "cB"]
686 l[-1:1:-1] = new_slice
687 root.c[-1:1:-1] = new_slice
688
689 self.assertEqual(["c1", "c2", "cB", "cA"], l)
690 self.assertEqual(["c1", "c2", "cB", "cA"],
691 [ c.text for c in root.c ])
692 self.assertEqual(l,
693 [ c.text for c in root.c ])
694
696 Element = self.Element
697 root = Element("root")
698 l = ["c1", "c2", "c3", "c4"]
699 root.c = l
700
701 self.assertEqual(["c1", "c2", "c3", "c4"],
702 [ c.text for c in root.c ])
703 self.assertEqual(l,
704 [ c.text for c in root.c ])
705
706 new_slice = ["cA", "cB"]
707 l[-1:-4:-2] = new_slice
708 root.c[-1:-4:-2] = new_slice
709
710 self.assertEqual(["c1", "cB", "c3", "cA"], l)
711 self.assertEqual(["c1", "cB", "c3", "cA"],
712 [ c.text for c in root.c ])
713 self.assertEqual(l,
714 [ c.text for c in root.c ])
715
716
717
719 Element = self.Element
720 root = Element("root")
721 root['child'] = ['CHILD1', 'CHILD2']
722 self.assertEqual(["CHILD1", "CHILD2"],
723 [ c.text for c in root.child ])
724
725 self.assertRaises(IndexError, operator.setitem, root.child, -3, 'oob')
726 self.assertRaises(IndexError, operator.setitem, root.child, -300, 'oob')
727 self.assertRaises(IndexError, operator.setitem, root.child, 2, 'oob')
728 self.assertRaises(IndexError, operator.setitem, root.child, 200, 'oob')
729
730 root.child[0] = "child0"
731 root.child[-1] = "child-1"
732 self.assertEqual(["child0", "child-1"],
733 [ c.text for c in root.child ])
734
735 root.child[1] = "child1"
736 root.child[-2] = "child-2"
737 self.assertEqual(["child-2", "child1"],
738 [ c.text for c in root.child ])
739
741
742 Element = self.Element
743 root = Element("root")
744 root['child'] = ['CHILD1', 'CHILD2', 'CHILD3', 'CHILD4']
745 self.assertEqual(["CHILD1", "CHILD2", "CHILD3", "CHILD4"],
746 [ c.text for c in root.child ])
747
748 del root.child[-1]
749 self.assertEqual(["CHILD1", "CHILD2", "CHILD3"],
750 [ c.text for c in root.child ])
751 del root.child[-2]
752 self.assertEqual(["CHILD1", "CHILD3"],
753 [ c.text for c in root.child ])
754 del root.child[0]
755 self.assertEqual(["CHILD3"],
756 [ c.text for c in root.child ])
757 del root.child[-1]
758 self.assertRaises(AttributeError, getattr, root, 'child')
759
767
775
777
778 Element = self.Element
779 root = Element("root")
780
781 root["text"] = "TEST"
782 self.assertEqual(["TEST"],
783 [ c.text for c in root["text"] ])
784
785 root["tail"] = "TEST"
786 self.assertEqual(["TEST"],
787 [ c.text for c in root["tail"] ])
788
789 root["pyval"] = "TEST"
790 self.assertEqual(["TEST"],
791 [ c.text for c in root["pyval"] ])
792
793 root["tag"] = "TEST"
794 self.assertEqual(["TEST"],
795 [ c.text for c in root["tag"] ])
796
804
806 XML = self.XML
807 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
808 self.assertEqual(2, len(root.findall(".//{X}b")))
809 self.assertEqual(3, len(root.findall(".//b")))
810 self.assertEqual(2, len(root.findall("b")))
811
819
834
840
842 Element = self.Element
843 SubElement = self.etree.SubElement
844 root = Element("{objectified}root")
845 root.bool = True
846 self.assertEqual(root.bool, True)
847 self.assertEqual(root.bool + root.bool, True + True)
848 self.assertEqual(True + root.bool, True + root.bool)
849 self.assertEqual(root.bool * root.bool, True * True)
850 self.assertEqual(int(root.bool), int(True))
851 self.assertEqual(hash(root.bool), hash(True))
852 self.assertEqual(complex(root.bool), complex(True))
853 self.assertTrue(isinstance(root.bool, objectify.BoolElement))
854
855 root.bool = False
856 self.assertEqual(root.bool, False)
857 self.assertEqual(root.bool + root.bool, False + False)
858 self.assertEqual(False + root.bool, False + root.bool)
859 self.assertEqual(root.bool * root.bool, False * False)
860 self.assertEqual(int(root.bool), int(False))
861 self.assertEqual(hash(root.bool), hash(False))
862 self.assertEqual(complex(root.bool), complex(False))
863 self.assertTrue(isinstance(root.bool, objectify.BoolElement))
864
873
880
887
894
906
916
937
942
947
952
957
966
971
976
981
988
995
1002
1014
1024
1029
1034
1039
1046
1051
1055
1062
1067
1071
1085
1090
1102
1109
1115
1124
1133
1139
1148
1150 pyval = 1
1151 pytype = "NoneType"
1152 objclass = objectify.NoneElement
1153 value = objectify.DataElement(pyval, _pytype=pytype)
1154 self.assertTrue(isinstance(value, objclass),
1155 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1156 % (pyval, pytype, type(value), objclass))
1157 self.assertEqual(value.text, None)
1158 self.assertEqual(value.pyval, None)
1159
1161
1162 pyval = 1
1163 pytype = "none"
1164 objclass = objectify.NoneElement
1165 value = objectify.DataElement(pyval, _pytype=pytype)
1166 self.assertTrue(isinstance(value, objclass),
1167 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1168 % (pyval, pytype, type(value), objclass))
1169 self.assertEqual(value.text, None)
1170 self.assertEqual(value.pyval, None)
1171
1177 root = Element("{objectified}root")
1178 root.myfloat = MyFloat(5.5)
1179 self.assertTrue(isinstance(root.myfloat, objectify.FloatElement))
1180 self.assertEqual(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
1181
1183 class MyFloat(float):
1184 pass
1185 value = objectify.DataElement(MyFloat(5.5))
1186 self.assertTrue(isinstance(value, objectify.FloatElement))
1187 self.assertEqual(value, 5.5)
1188 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), None)
1189
1191 XML = self.XML
1192 root = XML('''\
1193 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1194 <b xsi:type="boolean">true</b>
1195 <b xsi:type="boolean">false</b>
1196 <b xsi:type="boolean">1</b>
1197 <b xsi:type="boolean">0</b>
1198
1199 <f xsi:type="float">5</f>
1200 <f xsi:type="double">5</f>
1201
1202 <s xsi:type="string">5</s>
1203 <s xsi:type="normalizedString">5</s>
1204 <s xsi:type="token">5</s>
1205 <s xsi:type="language">5</s>
1206 <s xsi:type="Name">5</s>
1207 <s xsi:type="NCName">5</s>
1208 <s xsi:type="ID">5</s>
1209 <s xsi:type="IDREF">5</s>
1210 <s xsi:type="ENTITY">5</s>
1211 <s xsi:type="NMTOKEN">5</s>
1212
1213 <l xsi:type="integer">5</l>
1214 <l xsi:type="nonPositiveInteger">5</l>
1215 <l xsi:type="negativeInteger">5</l>
1216 <l xsi:type="long">5</l>
1217 <l xsi:type="nonNegativeInteger">5</l>
1218 <l xsi:type="unsignedLong">5</l>
1219 <l xsi:type="unsignedInt">5</l>
1220 <l xsi:type="positiveInteger">5</l>
1221
1222 <i xsi:type="int">5</i>
1223 <i xsi:type="short">5</i>
1224 <i xsi:type="byte">5</i>
1225 <i xsi:type="unsignedShort">5</i>
1226 <i xsi:type="unsignedByte">5</i>
1227
1228 <n xsi:nil="true"/>
1229 </root>
1230 ''')
1231
1232 for b in root.b:
1233 self.assertTrue(isinstance(b, objectify.BoolElement))
1234 self.assertEqual(True, root.b[0])
1235 self.assertEqual(False, root.b[1])
1236 self.assertEqual(True, root.b[2])
1237 self.assertEqual(False, root.b[3])
1238
1239 for f in root.f:
1240 self.assertTrue(isinstance(f, objectify.FloatElement))
1241 self.assertEqual(5, f)
1242
1243 for s in root.s:
1244 self.assertTrue(isinstance(s, objectify.StringElement))
1245 self.assertEqual("5", s)
1246
1247 for i in root.i:
1248 self.assertTrue(isinstance(i, objectify.IntElement))
1249 self.assertEqual(5, i)
1250
1251 for l in root.l:
1252 self.assertTrue(isinstance(l, objectify.IntElement))
1253 self.assertEqual(5, i)
1254
1255 self.assertTrue(isinstance(root.n, objectify.NoneElement))
1256 self.assertEqual(None, root.n)
1257
1259 XML = self.XML
1260 root = XML('''\
1261 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1262 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1263 <b xsi:type="xsd:boolean">true</b>
1264 <b xsi:type="xsd:boolean">false</b>
1265 <b xsi:type="xsd:boolean">1</b>
1266 <b xsi:type="xsd:boolean">0</b>
1267
1268 <f xsi:type="xsd:float">5</f>
1269 <f xsi:type="xsd:double">5</f>
1270
1271 <s xsi:type="xsd:string">5</s>
1272 <s xsi:type="xsd:normalizedString">5</s>
1273 <s xsi:type="xsd:token">5</s>
1274 <s xsi:type="xsd:language">5</s>
1275 <s xsi:type="xsd:Name">5</s>
1276 <s xsi:type="xsd:NCName">5</s>
1277 <s xsi:type="xsd:ID">5</s>
1278 <s xsi:type="xsd:IDREF">5</s>
1279 <s xsi:type="xsd:ENTITY">5</s>
1280 <s xsi:type="xsd:NMTOKEN">5</s>
1281
1282 <l xsi:type="xsd:integer">5</l>
1283 <l xsi:type="xsd:nonPositiveInteger">5</l>
1284 <l xsi:type="xsd:negativeInteger">5</l>
1285 <l xsi:type="xsd:long">5</l>
1286 <l xsi:type="xsd:nonNegativeInteger">5</l>
1287 <l xsi:type="xsd:unsignedLong">5</l>
1288 <l xsi:type="xsd:unsignedInt">5</l>
1289 <l xsi:type="xsd:positiveInteger">5</l>
1290
1291 <i xsi:type="xsd:int">5</i>
1292 <i xsi:type="xsd:short">5</i>
1293 <i xsi:type="xsd:byte">5</i>
1294 <i xsi:type="xsd:unsignedShort">5</i>
1295 <i xsi:type="xsd:unsignedByte">5</i>
1296
1297 <n xsi:nil="true"/>
1298 </root>
1299 ''')
1300
1301 for b in root.b:
1302 self.assertTrue(isinstance(b, objectify.BoolElement))
1303 self.assertEqual(True, root.b[0])
1304 self.assertEqual(False, root.b[1])
1305 self.assertEqual(True, root.b[2])
1306 self.assertEqual(False, root.b[3])
1307
1308 for f in root.f:
1309 self.assertTrue(isinstance(f, objectify.FloatElement))
1310 self.assertEqual(5, f)
1311
1312 for s in root.s:
1313 self.assertTrue(isinstance(s, objectify.StringElement))
1314 self.assertEqual("5", s)
1315
1316 for i in root.i:
1317 self.assertTrue(isinstance(i, objectify.IntElement))
1318 self.assertEqual(5, i)
1319
1320 for l in root.l:
1321 self.assertTrue(isinstance(l, objectify.IntElement))
1322 self.assertEqual(5, l)
1323
1324 self.assertTrue(isinstance(root.n, objectify.NoneElement))
1325 self.assertEqual(None, root.n)
1326
1328 XML = self.XML
1329 root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
1330 strs = [ str(s) for s in root.b ]
1331 self.assertEqual(["why", "try"],
1332 strs)
1333
1335 XML = self.XML
1336 root = XML(_bytes('<root><b>test</b><b>taste</b><b></b><b/></root>'))
1337 self.assertFalse(root.b[0] < root.b[1])
1338 self.assertFalse(root.b[0] <= root.b[1])
1339 self.assertFalse(root.b[0] == root.b[1])
1340
1341 self.assertTrue(root.b[0] != root.b[1])
1342 self.assertTrue(root.b[0] >= root.b[1])
1343 self.assertTrue(root.b[0] > root.b[1])
1344
1345 self.assertEqual(root.b[0], "test")
1346 self.assertEqual("test", root.b[0])
1347
1348 self.assertEqual("", root.b[2])
1349 self.assertEqual(root.b[2], "")
1350 self.assertEqual("", root.b[3])
1351 self.assertEqual(root.b[3], "")
1352 self.assertEqual(root.b[2], root.b[3])
1353
1354 root.b = "test"
1355 self.assertTrue(root.b)
1356 root.b = ""
1357 self.assertFalse(root.b)
1358 self.assertEqual(root.b, "")
1359 self.assertEqual("", root.b)
1360
1362 XML = self.XML
1363 root = XML(_bytes('<root><b>5</b><b>6</b></root>'))
1364 self.assertTrue(root.b[0] < root.b[1])
1365 self.assertTrue(root.b[0] <= root.b[1])
1366 self.assertTrue(root.b[0] != root.b[1])
1367
1368 self.assertFalse(root.b[0] == root.b[1])
1369 self.assertFalse(root.b[0] >= root.b[1])
1370 self.assertFalse(root.b[0] > root.b[1])
1371
1372 self.assertEqual(root.b[0], 5)
1373 self.assertEqual(5, root.b[0])
1374 self.assertNotEqual(root.b[0], "5")
1375
1376 root.b = 5
1377 self.assertTrue(root.b)
1378 root.b = 0
1379 self.assertFalse(root.b)
1380
1381
1382
1384 XML = self.XML
1385 root = XML(_bytes('<root><b>false</b><b>true</b></root>'))
1386 self.assertTrue(root.b[0] < root.b[1])
1387 self.assertTrue(root.b[0] <= root.b[1])
1388 self.assertTrue(root.b[0] != root.b[1])
1389
1390 self.assertFalse(root.b[0] == root.b[1])
1391 self.assertFalse(root.b[0] >= root.b[1])
1392 self.assertFalse(root.b[0] > root.b[1])
1393
1394 self.assertFalse(root.b[0])
1395 self.assertTrue(root.b[1])
1396
1397 self.assertEqual(root.b[0], False)
1398 self.assertEqual(False, root.b[0])
1399 self.assertTrue(root.b[0] < 5)
1400 self.assertTrue(5 > root.b[0])
1401
1402 root.b = True
1403 self.assertTrue(root.b)
1404 root.b = False
1405 self.assertFalse(root.b)
1406
1408 XML = self.XML
1409 root = XML(_bytes("""
1410 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1411 <b xsi:nil="true"></b><b xsi:nil="true"/>
1412 </root>"""))
1413 self.assertTrue(root.b[0] == root.b[1])
1414 self.assertFalse(root.b[0])
1415 self.assertEqual(root.b[0], None)
1416 self.assertEqual(None, root.b[0])
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1432
1439
1443
1445 XML = self.XML
1446 root = XML(_bytes('''\
1447 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1448 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1449 <b>5</b>
1450 <b>test</b>
1451 <c>1.1</c>
1452 <c>\uF8D2</c>
1453 <x>true</x>
1454 <n xsi:nil="true" />
1455 <n></n>
1456 <b xsi:type="double">5</b>
1457 <b xsi:type="float">5</b>
1458 <s xsi:type="string">23</s>
1459 <s py:pytype="str">42</s>
1460 <f py:pytype="float">300</f>
1461 <l py:pytype="long">2</l>
1462 <t py:pytype="TREE"></t>
1463 </a>
1464 '''))
1465 objectify.annotate(root)
1466
1467 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1468 for c in root.iterchildren() ]
1469 self.assertEqual("int", child_types[ 0])
1470 self.assertEqual("str", child_types[ 1])
1471 self.assertEqual("float", child_types[ 2])
1472 self.assertEqual("str", child_types[ 3])
1473 self.assertEqual("bool", child_types[ 4])
1474 self.assertEqual("NoneType", child_types[ 5])
1475 self.assertEqual(None, child_types[ 6])
1476 self.assertEqual("float", child_types[ 7])
1477 self.assertEqual("float", child_types[ 8])
1478 self.assertEqual("str", child_types[ 9])
1479 self.assertEqual("int", child_types[10])
1480 self.assertEqual("int", child_types[11])
1481 self.assertEqual("int", child_types[12])
1482 self.assertEqual(None, child_types[13])
1483
1484 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1485
1505
1507 XML = self.XML
1508 root = XML(_bytes('''\
1509 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1510 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1511 <b>5</b>
1512 <b>test</b>
1513 <c>1.1</c>
1514 <c>\uF8D2</c>
1515 <x>true</x>
1516 <n xsi:nil="true" />
1517 <n></n>
1518 <b xsi:type="double">5</b>
1519 <b xsi:type="float">5</b>
1520 <s xsi:type="string">23</s>
1521 <s py:pytype="str">42</s>
1522 <f py:pytype="float">300</f>
1523 <l py:pytype="long">2</l>
1524 <t py:pytype="TREE"></t>
1525 </a>
1526 '''))
1527 objectify.annotate(root, ignore_old=False)
1528
1529 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1530 for c in root.iterchildren() ]
1531 self.assertEqual("int", child_types[ 0])
1532 self.assertEqual("str", child_types[ 1])
1533 self.assertEqual("float", child_types[ 2])
1534 self.assertEqual("str", child_types[ 3])
1535 self.assertEqual("bool", child_types[ 4])
1536 self.assertEqual("NoneType", child_types[ 5])
1537 self.assertEqual(None, child_types[ 6])
1538 self.assertEqual("float", child_types[ 7])
1539 self.assertEqual("float", child_types[ 8])
1540 self.assertEqual("str", child_types[ 9])
1541 self.assertEqual("str", child_types[10])
1542 self.assertEqual("float", child_types[11])
1543 self.assertEqual("int", child_types[12])
1544 self.assertEqual(TREE_PYTYPE, child_types[13])
1545
1546 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1547
1549 XML = self.XML
1550 root = XML(_bytes('''\
1551 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1552 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1553 <b>5</b>
1554 <b>test</b>
1555 <c>1.1</c>
1556 <c>\uF8D2</c>
1557 <x>true</x>
1558 <n xsi:nil="true" />
1559 <n></n>
1560 <b xsi:type="double">5</b>
1561 <b xsi:type="float">5</b>
1562 <s xsi:type="string">23</s>
1563 <s py:pytype="str">42</s>
1564 <f py:pytype="float">300</f>
1565 <l py:pytype="long">2</l>
1566 <t py:pytype="TREE"></t>
1567 </a>
1568 '''))
1569 objectify.annotate(root, ignore_old=False, ignore_xsi=False,
1570 annotate_xsi=1, annotate_pytype=1)
1571
1572
1573 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1574 for c in root.iterchildren() ]
1575 self.assertEqual("int", child_types[ 0])
1576 self.assertEqual("str", child_types[ 1])
1577 self.assertEqual("float", child_types[ 2])
1578 self.assertEqual("str", child_types[ 3])
1579 self.assertEqual("bool", child_types[ 4])
1580 self.assertEqual("NoneType", child_types[ 5])
1581 self.assertEqual(None, child_types[ 6])
1582 self.assertEqual("float", child_types[ 7])
1583 self.assertEqual("float", child_types[ 8])
1584 self.assertEqual("str", child_types[ 9])
1585 self.assertEqual("str", child_types[10])
1586 self.assertEqual("float", child_types[11])
1587 self.assertEqual("int", child_types[12])
1588 self.assertEqual(TREE_PYTYPE, child_types[13])
1589
1590 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1591
1592 child_xsitypes = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1593 for c in root.iterchildren() ]
1594
1595
1596 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1597 for c in root.iterchildren() ]
1598 self.assertEqual("xsd:integer", child_types[ 0])
1599 self.assertEqual("xsd:string", child_types[ 1])
1600 self.assertEqual("xsd:double", child_types[ 2])
1601 self.assertEqual("xsd:string", child_types[ 3])
1602 self.assertEqual("xsd:boolean", child_types[ 4])
1603 self.assertEqual(None, child_types[ 5])
1604 self.assertEqual(None, child_types[ 6])
1605 self.assertEqual("xsd:double", child_types[ 7])
1606 self.assertEqual("xsd:float", child_types[ 8])
1607 self.assertEqual("xsd:string", child_types[ 9])
1608 self.assertEqual("xsd:string", child_types[10])
1609 self.assertEqual("xsd:double", child_types[11])
1610 self.assertEqual("xsd:integer", child_types[12])
1611 self.assertEqual(None, child_types[13])
1612
1613 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1614
1616 XML = self.XML
1617 root = XML(_bytes('''\
1618 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1619 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1620 <b>5</b>
1621 <b>test</b>
1622 <c>1.1</c>
1623 <c>\uF8D2</c>
1624 <x>true</x>
1625 <n xsi:nil="true" />
1626 <n></n>
1627 <b xsi:type="double">5</b>
1628 <b xsi:type="float">5</b>
1629 <s xsi:type="string">23</s>
1630 <s py:pytype="str">42</s>
1631 <f py:pytype="float">300</f>
1632 <l py:pytype="long">2</l>
1633 <t py:pytype="TREE"></t>
1634 </a>
1635 '''))
1636 objectify.xsiannotate(root, ignore_old=False)
1637
1638 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1639 for c in root.iterchildren() ]
1640 self.assertEqual("xsd:integer", child_types[ 0])
1641 self.assertEqual("xsd:string", child_types[ 1])
1642 self.assertEqual("xsd:double", child_types[ 2])
1643 self.assertEqual("xsd:string", child_types[ 3])
1644 self.assertEqual("xsd:boolean", child_types[ 4])
1645 self.assertEqual(None, child_types[ 5])
1646 self.assertEqual(None, child_types[ 6])
1647 self.assertEqual("xsd:double", child_types[ 7])
1648 self.assertEqual("xsd:float", child_types[ 8])
1649 self.assertEqual("xsd:string", child_types[ 9])
1650 self.assertEqual("xsd:string", child_types[10])
1651 self.assertEqual("xsd:double", child_types[11])
1652 self.assertEqual("xsd:integer", child_types[12])
1653 self.assertEqual(None, child_types[13])
1654
1656 XML = self.XML
1657 root = XML(_bytes('''\
1658 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1659 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1660 <b>5</b>
1661 <b>test</b>
1662 <c>1.1</c>
1663 <c>\uF8D2</c>
1664 <x>true</x>
1665 <n xsi:nil="true" />
1666 <n></n>
1667 <b xsi:type="double">5</b>
1668 <b xsi:type="float">5</b>
1669 <s xsi:type="string">23</s>
1670 <s py:pytype="str">42</s>
1671 <f py:pytype="float">300</f>
1672 <l py:pytype="long">2</l>
1673 <t py:pytype="TREE"></t>
1674 </a>
1675 '''))
1676 objectify.pyannotate(root, ignore_old=True)
1677
1678 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1679 for c in root.iterchildren() ]
1680 self.assertEqual("int", child_types[ 0])
1681 self.assertEqual("str", child_types[ 1])
1682 self.assertEqual("float", child_types[ 2])
1683 self.assertEqual("str", child_types[ 3])
1684 self.assertEqual("bool", child_types[ 4])
1685 self.assertEqual("NoneType", child_types[ 5])
1686 self.assertEqual(None, child_types[ 6])
1687 self.assertEqual("float", child_types[ 7])
1688 self.assertEqual("float", child_types[ 8])
1689 self.assertEqual("str", child_types[ 9])
1690 self.assertEqual("int", child_types[10])
1691 self.assertEqual("int", child_types[11])
1692 self.assertEqual("int", child_types[12])
1693 self.assertEqual(None, child_types[13])
1694
1695 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1696
1716
1718 XML = self.XML
1719 root = XML('''\
1720 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1721 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1722 <b>5</b>
1723 <b>test</b>
1724 <c>1.1</c>
1725 <c>\uF8D2</c>
1726 <x>true</x>
1727 <n xsi:nil="true" />
1728 <n></n>
1729 <b xsi:type="double">5</b>
1730 <b xsi:type="float">5</b>
1731 <s xsi:type="string">23</s>
1732 <s py:pytype="str">42</s>
1733 <f py:pytype="float">300</f>
1734 <l py:pytype="long">2</l>
1735 <t py:pytype="TREE"></t>
1736 </a>
1737 ''')
1738 objectify.pyannotate(root)
1739
1740 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1741 for c in root.iterchildren() ]
1742 self.assertEqual("int", child_types[ 0])
1743 self.assertEqual("str", child_types[ 1])
1744 self.assertEqual("float", child_types[ 2])
1745 self.assertEqual("str", child_types[ 3])
1746 self.assertEqual("bool", child_types[ 4])
1747 self.assertEqual("NoneType", child_types[ 5])
1748 self.assertEqual(None, child_types[ 6])
1749 self.assertEqual("float", child_types[ 7])
1750 self.assertEqual("float", child_types[ 8])
1751 self.assertEqual("str", child_types[ 9])
1752 self.assertEqual("str", child_types[10])
1753 self.assertEqual("float", child_types[11])
1754 self.assertEqual("int", child_types[12])
1755 self.assertEqual(TREE_PYTYPE, child_types[13])
1756
1757 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1758
1760 XML = self.XML
1761 root = XML(_bytes('''\
1762 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1763 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1764 <b>5</b>
1765 <b>test</b>
1766 <c>1.1</c>
1767 <c>\uF8D2</c>
1768 <x>true</x>
1769 <n xsi:nil="true" />
1770 <n></n>
1771 <b xsi:type="double">5</b>
1772 <b xsi:type="float">5</b>
1773 <s xsi:type="string">23</s>
1774 <s py:pytype="str">42</s>
1775 <f py:pytype="float">300</f>
1776 <l py:pytype="long">2</l>
1777 <t py:pytype="TREE"></t>
1778 </a>
1779 '''))
1780 objectify.xsiannotate(root, ignore_old=True)
1781
1782 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1783 for c in root.iterchildren() ]
1784 self.assertEqual("xsd:integer", child_types[ 0])
1785 self.assertEqual("xsd:string", child_types[ 1])
1786 self.assertEqual("xsd:double", child_types[ 2])
1787 self.assertEqual("xsd:string", child_types[ 3])
1788 self.assertEqual("xsd:boolean", child_types[ 4])
1789 self.assertEqual(None, child_types[ 5])
1790 self.assertEqual(None, child_types[ 6])
1791 self.assertEqual("xsd:integer", child_types[ 7])
1792 self.assertEqual("xsd:integer", child_types[ 8])
1793 self.assertEqual("xsd:integer", child_types[ 9])
1794 self.assertEqual("xsd:string", child_types[10])
1795 self.assertEqual("xsd:double", child_types[11])
1796 self.assertEqual("xsd:integer", child_types[12])
1797 self.assertEqual(None, child_types[13])
1798
1799 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1800
1802 XML = self.XML
1803 root = XML(_bytes('''\
1804 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1805 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1806 <b>5</b>
1807 <b>test</b>
1808 <c>1.1</c>
1809 <c>\uF8D2</c>
1810 <x>true</x>
1811 <n xsi:nil="true" />
1812 <n></n>
1813 <b xsi:type="double">5</b>
1814 <b xsi:type="float">5</b>
1815 <s xsi:type="string">23</s>
1816 <s py:pytype="str">42</s>
1817 <f py:pytype="float">300</f>
1818 <l py:pytype="long">2</l>
1819 <t py:pytype="TREE"></t>
1820 </a>
1821 '''))
1822 objectify.deannotate(root)
1823
1824 for c in root.getiterator():
1825 self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1826 self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1827
1828 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1829
1831 XML = self.XML
1832 root = XML(_bytes('''\
1833 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1834 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1835 <b>5</b>
1836 <b>test</b>
1837 <c>1.1</c>
1838 <c>\uF8D2</c>
1839 <x>true</x>
1840 <n xsi:nil="true" />
1841 <n></n>
1842 <b xsi:type="double">5</b>
1843 <b xsi:type="float">5</b>
1844 <s xsi:type="string">23</s>
1845 <s py:pytype="str">42</s>
1846 <f py:pytype="float">300</f>
1847 <l py:pytype="long">2</l>
1848 <t py:pytype="TREE"></t>
1849 </a>
1850 '''))
1851 objectify.annotate(
1852 root, ignore_old=False, ignore_xsi=False, annotate_xsi=True,
1853 empty_pytype='str', empty_type='string')
1854 objectify.deannotate(root, pytype=False, xsi=False, xsi_nil=True)
1855
1856 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1857 for c in root.iterchildren() ]
1858 self.assertEqual("xsd:integer", child_types[ 0])
1859 self.assertEqual("xsd:string", child_types[ 1])
1860 self.assertEqual("xsd:double", child_types[ 2])
1861 self.assertEqual("xsd:string", child_types[ 3])
1862 self.assertEqual("xsd:boolean", child_types[ 4])
1863 self.assertEqual(None, child_types[ 5])
1864 self.assertEqual("xsd:string", child_types[ 6])
1865 self.assertEqual("xsd:double", child_types[ 7])
1866 self.assertEqual("xsd:float", child_types[ 8])
1867 self.assertEqual("xsd:string", child_types[ 9])
1868 self.assertEqual("xsd:string", child_types[10])
1869 self.assertEqual("xsd:double", child_types[11])
1870 self.assertEqual("xsd:integer", child_types[12])
1871 self.assertEqual(None, child_types[13])
1872
1873 self.assertEqual(None, root.n.get(XML_SCHEMA_NIL_ATTR))
1874
1875 for c in root.iterchildren():
1876 self.assertNotEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1877
1878 if (c.get(objectify.PYTYPE_ATTRIBUTE) not in [TREE_PYTYPE,
1879 "NoneType"]):
1880 self.assertNotEqual(
1881 None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1882
1884 XML = self.XML
1885 root = XML(_bytes('''\
1886 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1887 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1888 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1889 <b>5</b>
1890 <b>test</b>
1891 <c>1.1</c>
1892 <c>\uF8D2</c>
1893 <x>true</x>
1894 <n xsi:nil="true" />
1895 <n></n>
1896 <b xsi:type="xsd:double">5</b>
1897 <b xsi:type="xsd:float">5</b>
1898 <s xsi:type="xsd:string">23</s>
1899 <s py:pytype="str">42</s>
1900 <f py:pytype="float">300</f>
1901 <l py:pytype="long">2</l>
1902 <t py:pytype="TREE"></t>
1903 </a>
1904 '''))
1905 objectify.annotate(root)
1906 objectify.deannotate(root, pytype=False)
1907
1908 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1909 for c in root.iterchildren() ]
1910 self.assertEqual("int", child_types[ 0])
1911 self.assertEqual("str", child_types[ 1])
1912 self.assertEqual("float", child_types[ 2])
1913 self.assertEqual("str", child_types[ 3])
1914 self.assertEqual("bool", child_types[ 4])
1915 self.assertEqual("NoneType", child_types[ 5])
1916 self.assertEqual(None, child_types[ 6])
1917 self.assertEqual("float", child_types[ 7])
1918 self.assertEqual("float", child_types[ 8])
1919 self.assertEqual("str", child_types[ 9])
1920 self.assertEqual("int", child_types[10])
1921 self.assertEqual("int", child_types[11])
1922 self.assertEqual("int", child_types[12])
1923 self.assertEqual(None, child_types[13])
1924
1925 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1926
1927 for c in root.getiterator():
1928 self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1929
1931 XML = self.XML
1932 root = XML(_bytes('''\
1933 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1934 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1935 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1936 <b xsi:type="xsd:int">5</b>
1937 <b xsi:type="xsd:string">test</b>
1938 <c xsi:type="xsd:float">1.1</c>
1939 <c xsi:type="xsd:string">\uF8D2</c>
1940 <x xsi:type="xsd:boolean">true</x>
1941 <n xsi:nil="true" />
1942 <n></n>
1943 <b xsi:type="xsd:double">5</b>
1944 <b xsi:type="xsd:float">5</b>
1945 <s xsi:type="xsd:string">23</s>
1946 <s xsi:type="xsd:string">42</s>
1947 <f xsi:type="xsd:float">300</f>
1948 <l xsi:type="xsd:long">2</l>
1949 <t py:pytype="TREE"></t>
1950 </a>
1951 '''))
1952 objectify.annotate(root)
1953 objectify.deannotate(root, xsi=False)
1954
1955 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1956 for c in root.iterchildren() ]
1957 self.assertEqual("xsd:int", child_types[ 0])
1958 self.assertEqual("xsd:string", child_types[ 1])
1959 self.assertEqual("xsd:float", child_types[ 2])
1960 self.assertEqual("xsd:string", child_types[ 3])
1961 self.assertEqual("xsd:boolean", child_types[ 4])
1962 self.assertEqual(None, child_types[ 5])
1963 self.assertEqual(None, child_types[ 6])
1964 self.assertEqual("xsd:double", child_types[ 7])
1965 self.assertEqual("xsd:float", child_types[ 8])
1966 self.assertEqual("xsd:string", child_types[ 9])
1967 self.assertEqual("xsd:string", child_types[10])
1968 self.assertEqual("xsd:float", child_types[11])
1969 self.assertEqual("xsd:long", child_types[12])
1970 self.assertEqual(None, child_types[13])
1971
1972 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1973
1974 for c in root.getiterator():
1975 self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1976
1978 XML = self.XML
1979
1980 xml = _bytes('''\
1981 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1982 <b>5</b>
1983 <b>test</b>
1984 <c>1.1</c>
1985 <c>\uF8D2</c>
1986 <x>true</x>
1987 <n xsi:nil="true" />
1988 <n></n>
1989 <b xsi:type="double">5</b>
1990 </a>
1991 ''')
1992
1993 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1994 objectify.set_pytype_attribute_tag("{TEST}test")
1995
1996 root = XML(xml)
1997 objectify.annotate(root)
1998
1999 attribs = root.xpath("//@py:%s" % pytype_name,
2000 namespaces={"py" : pytype_ns})
2001 self.assertEqual(0, len(attribs))
2002 attribs = root.xpath("//@py:test",
2003 namespaces={"py" : "TEST"})
2004 self.assertEqual(7, len(attribs))
2005
2006 objectify.set_pytype_attribute_tag()
2007 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
2008
2009 self.assertNotEqual("test", pytype_ns.lower())
2010 self.assertNotEqual("test", pytype_name.lower())
2011
2012 root = XML(xml)
2013 attribs = root.xpath("//@py:%s" % pytype_name,
2014 namespaces={"py" : pytype_ns})
2015 self.assertEqual(0, len(attribs))
2016
2017 objectify.annotate(root)
2018 attribs = root.xpath("//@py:%s" % pytype_name,
2019 namespaces={"py" : pytype_ns})
2020 self.assertEqual(7, len(attribs))
2021
2029
2030 def checkMyType(s):
2031 return True
2032
2033 pytype = objectify.PyType("mytype", checkMyType, NewType)
2034 self.assertTrue(pytype not in objectify.getRegisteredTypes())
2035 pytype.register()
2036 self.assertTrue(pytype in objectify.getRegisteredTypes())
2037 pytype.unregister()
2038 self.assertTrue(pytype not in objectify.getRegisteredTypes())
2039
2040 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
2041 self.assertEqual(pytype, objectify.getRegisteredTypes()[0])
2042 pytype.unregister()
2043
2044 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
2045 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
2046 pytype.unregister()
2047
2048 self.assertRaises(ValueError, pytype.register,
2049 before = [objectify.getRegisteredTypes()[0].name],
2050 after = [objectify.getRegisteredTypes()[1].name])
2051
2053 from datetime import datetime
2054 def parse_date(value):
2055 if len(value) != 14:
2056 raise ValueError(value)
2057 Y = int(value[0:4])
2058 M = int(value[4:6])
2059 D = int(value[6:8])
2060 h = int(value[8:10])
2061 m = int(value[10:12])
2062 s = int(value[12:14])
2063 return datetime(Y, M, D, h, m, s)
2064
2065 def stringify_date(date):
2066 return date.strftime("%Y%m%d%H%M%S")
2067
2068 class DatetimeElement(objectify.ObjectifiedDataElement):
2069 def pyval(self):
2070 return parse_date(self.text)
2071 pyval = property(pyval)
2072
2073 datetime_type = objectify.PyType(
2074 "datetime", parse_date, DatetimeElement, stringify_date)
2075 datetime_type.xmlSchemaTypes = "dateTime"
2076 datetime_type.register()
2077
2078 NAMESPACE = "http://foo.net/xmlns"
2079 NAMESPACE_MAP = {'ns': NAMESPACE}
2080
2081 r = objectify.Element("{%s}root" % NAMESPACE, nsmap=NAMESPACE_MAP)
2082 time = datetime.now()
2083 r.date = time
2084
2085 self.assertTrue(isinstance(r.date, DatetimeElement))
2086 self.assertTrue(isinstance(r.date.pyval, datetime))
2087
2088 self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
2089 self.assertEqual(r.date.text, stringify_date(time))
2090
2091 r.date = objectify.E.date(time)
2092
2093 self.assertTrue(isinstance(r.date, DatetimeElement))
2094 self.assertTrue(isinstance(r.date.pyval, datetime))
2095
2096 self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
2097 self.assertEqual(r.date.text, stringify_date(time))
2098
2099 date = objectify.DataElement(time)
2100
2101 self.assertTrue(isinstance(date, DatetimeElement))
2102 self.assertTrue(isinstance(date.pyval, datetime))
2103
2104 self.assertEqual(date.pyval, parse_date(stringify_date(time)))
2105 self.assertEqual(date.text, stringify_date(time))
2106
2112
2118
2123
2132
2139
2147
2150
2153
2172
2177
2182
2187
2192
2212
2214 root = self.XML(xml_str)
2215 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
2216 self.assertEqual(root.c1.c2.text, path(root).text)
2217
2218 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
2219 self.assertEqual(root.c1.c2[2].text, path(root).text)
2220
2221 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
2222 self.assertEqual(root.c1.c2[2].text, path(root).text)
2223
2224 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
2225 self.assertEqual(root.c1.c2[-1].text, path(root).text)
2226
2227 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
2228 self.assertEqual(root.c1.c2[-3].text, path(root).text)
2229
2231 self.assertRaises(ValueError, objectify.ObjectPath,
2232 "root.c1[0].c2[-1-2]")
2233 self.assertRaises(ValueError, objectify.ObjectPath,
2234 ['root', 'c1[0]', 'c2[-1-2]'])
2235
2236 self.assertRaises(ValueError, objectify.ObjectPath,
2237 "root[2].c1.c2")
2238 self.assertRaises(ValueError, objectify.ObjectPath,
2239 ['root[2]', 'c1', 'c2'])
2240
2241 self.assertRaises(ValueError, objectify.ObjectPath,
2242 [])
2243 self.assertRaises(ValueError, objectify.ObjectPath,
2244 ['', '', ''])
2245
2247 root = self.XML(xml_str)
2248 path = objectify.ObjectPath("root.c1[9999].c2")
2249 self.assertRaises(AttributeError, path, root)
2250
2251 path = objectify.ObjectPath("root.c1[0].c2[9999]")
2252 self.assertRaises(AttributeError, path, root)
2253
2254 path = objectify.ObjectPath(".c1[9999].c2[0]")
2255 self.assertRaises(AttributeError, path, root)
2256
2257 path = objectify.ObjectPath("root.c1[-2].c2")
2258 self.assertRaises(AttributeError, path, root)
2259
2260 path = objectify.ObjectPath("root.c1[0].c2[-4]")
2261 self.assertRaises(AttributeError, path, root)
2262
2276
2278 root = self.XML(xml_str)
2279 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
2280 self.assertEqual(root.c1.c2.text, path.find(root).text)
2281 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
2282 self.assertEqual(root.c1.c2.text, path.find(root).text)
2283 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
2284 self.assertEqual(root.c1.c2.text, path.find(root).text)
2285 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
2286 self.assertEqual(root.c1.c2[2].text, path.find(root).text)
2287 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
2288 self.assertEqual(root.c1.c2.text, path.find(root).text)
2289 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
2290 self.assertEqual(root.c1.c2[2].text, path.find(root).text)
2291 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
2292 self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
2293 path.find(root).text)
2294
2307
2322
2334
2348
2350 root = self.XML(xml_str)
2351 path = objectify.ObjectPath( "root.c1.c99" )
2352 self.assertRaises(AttributeError, path.find, root)
2353
2354 new_el = self.Element("{objectified}test")
2355 new_el.a = ["TEST1", "TEST2"]
2356 new_el.a[0].set("myattr", "ATTR1")
2357 new_el.a[1].set("myattr", "ATTR2")
2358
2359 path.setattr(root, list(new_el.a))
2360
2361 self.assertEqual(2, len(root.c1.c99))
2362 self.assertEqual("ATTR1", root.c1.c99[0].get("myattr"))
2363 self.assertEqual("TEST1", root.c1.c99[0].text)
2364 self.assertEqual("ATTR2", root.c1.c99[1].get("myattr"))
2365 self.assertEqual("TEST2", root.c1.c99[1].text)
2366 self.assertEqual("TEST1", path(root).text)
2367
2376
2390
2402
2416
2431
2433 root = self.XML(xml_str)
2434 self.assertEqual(
2435 ['{objectified}root', '{objectified}root.c1',
2436 '{objectified}root.c1.c2',
2437 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
2438 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
2439 root.descendantpaths())
2440
2442 root = self.XML(xml_str)
2443 self.assertEqual(
2444 ['{objectified}c1', '{objectified}c1.c2',
2445 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
2446 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
2447 root.c1.descendantpaths())
2448
2450 root = self.XML(xml_str)
2451 self.assertEqual(
2452 ['root.{objectified}c1', 'root.{objectified}c1.c2',
2453 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
2454 'root.{objectified}c1.{otherNS}c2',
2455 'root.{objectified}c1.{}c2'],
2456 root.c1.descendantpaths('root'))
2457
2469
2482
2486
2490
2494
2500
2505
2507 import pickle
2508 if isinstance(stringOrElt, (etree._Element, etree._ElementTree)):
2509 elt = stringOrElt
2510 else:
2511 elt = self.XML(stringOrElt)
2512 out = BytesIO()
2513 pickle.dump(elt, out)
2514
2515 new_elt = pickle.loads(out.getvalue())
2516 self.assertEqual(
2517 etree.tostring(new_elt),
2518 etree.tostring(elt))
2519
2520
2521
2526
2531
2536
2541
2546
2551
2556
2561
2563 E = objectify.E
2564 DataElement = objectify.DataElement
2565 root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
2566 DataElement(2.0))
2567 self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
2568 self.assertEqual(root.text, "text")
2569 self.assertTrue(isinstance(root.sub, objectify.ObjectifiedElement))
2570 self.assertEqual(root.sub.tail, "tail")
2571 self.assertTrue(isinstance(root.sub.subsub, objectify.StringElement))
2572 self.assertEqual(len(root.value), 2)
2573 self.assertTrue(isinstance(root.value[0], objectify.IntElement))
2574 self.assertTrue(isinstance(root.value[1], objectify.FloatElement))
2575
2582
2583 attr = Attribute()
2584 self.assertEqual(attr.text, None)
2585 self.assertEqual(attr.get("datatype"), "TYPE")
2586 self.assertEqual(attr.get("range"), "0.,1.")
2587
2592
2599
2604
2610
2612 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2613 self.assertEqual(root.base, "http://no/such/url")
2614 self.assertEqual(
2615 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2616 root.base = "https://secret/url"
2617 self.assertEqual(root.base, "https://secret/url")
2618 self.assertEqual(
2619 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2620 "https://secret/url")
2621
2623 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2624 self.assertEqual(root.base, "http://no/such/url")
2625 self.assertEqual(
2626 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2627 root.set('{http://www.w3.org/XML/1998/namespace}base',
2628 "https://secret/url")
2629 self.assertEqual(root.base, "https://secret/url")
2630 self.assertEqual(
2631 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2632 "https://secret/url")
2633
2635 XML = self.XML
2636
2637 xml = _bytes('''\
2638 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2639 <i>5</i>
2640 <i>-5</i>
2641 <l>4294967296</l>
2642 <l>-4294967296</l>
2643 <f>1.1</f>
2644 <b>true</b>
2645 <b>false</b>
2646 <s>Strange things happen, where strings collide</s>
2647 <s>True</s>
2648 <s>False</s>
2649 <s>t</s>
2650 <s>f</s>
2651 <s></s>
2652 <s>None</s>
2653 <n xsi:nil="true" />
2654 </root>
2655 ''')
2656 root = XML(xml)
2657
2658 for i in root.i:
2659 self.assertTrue(isinstance(i, objectify.IntElement))
2660 for l in root.l:
2661 self.assertTrue(isinstance(l, objectify.IntElement))
2662 for f in root.f:
2663 self.assertTrue(isinstance(f, objectify.FloatElement))
2664 for b in root.b:
2665 self.assertTrue(isinstance(b, objectify.BoolElement))
2666 self.assertEqual(True, root.b[0])
2667 self.assertEqual(False, root.b[1])
2668 for s in root.s:
2669 self.assertTrue(isinstance(s, objectify.StringElement))
2670 self.assertTrue(isinstance(root.n, objectify.NoneElement))
2671 self.assertEqual(None, root.n)
2672
2674 suite = unittest.TestSuite()
2675 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
2676 suite.addTests(doctest.DocTestSuite(objectify))
2677 suite.addTests([make_doctest('../../../doc/objectify.txt')])
2678 return suite
2679
2680 if __name__ == '__main__':
2681 print('to test use test.py %s' % __file__)
2682