1
2
3 """
4 Tests specific to the lxml.objectify API
5 """
6
7
8 import unittest, operator, sys, os.path
9
10 this_dir = os.path.dirname(__file__)
11 if this_dir not in sys.path:
12 sys.path.insert(0, this_dir)
13
14 from common_imports import etree, HelperTestCase, fileInTestDir
15 from common_imports import SillyFileLike, canonicalize, doctest, make_doctest
16 from common_imports import _bytes, _str, StringIO, BytesIO
17
18 from lxml import objectify
19
20 PYTYPE_NAMESPACE = "http://codespeak.net/lxml/objectify/pytype"
21 XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
22 XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
23 XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
24 XML_SCHEMA_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
25 TREE_PYTYPE = "TREE"
26 DEFAULT_NSMAP = { "py" : PYTYPE_NAMESPACE,
27 "xsi" : XML_SCHEMA_INSTANCE_NS,
28 "xsd" : XML_SCHEMA_NS}
29
30 objectclass2xsitype = {
31
32 objectify.IntElement: ("int", "short", "byte", "unsignedShort",
33 "unsignedByte", "integer", "nonPositiveInteger",
34 "negativeInteger", "long", "nonNegativeInteger",
35 "unsignedLong", "unsignedInt", "positiveInteger",),
36 objectify.FloatElement: ("float", "double"),
37 objectify.BoolElement: ("boolean",),
38 objectify.StringElement: ("string", "normalizedString", "token", "language",
39 "Name", "NCName", "ID", "IDREF", "ENTITY",
40 "NMTOKEN", ),
41
42 }
43
44 xsitype2objclass = dict([ (v, k) for k in objectclass2xsitype
45 for v in objectclass2xsitype[k] ])
46
47 objectclass2pytype = {
48
49 objectify.IntElement: "int",
50 objectify.FloatElement: "float",
51 objectify.BoolElement: "bool",
52 objectify.StringElement: "str",
53
54 }
55
56 pytype2objclass = dict([ (objectclass2pytype[k], k)
57 for k in objectclass2pytype])
58
59 xml_str = '''\
60 <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
61 <obj:c1 a1="A1" a2="A2" other:a3="A3">
62 <obj:c2>0</obj:c2>
63 <obj:c2>1</obj:c2>
64 <obj:c2>2</obj:c2>
65 <other:c2>3</other:c2>
66 <c2>3</c2>
67 </obj:c1>
68 </obj:root>'''
69
71 """Test cases for lxml.objectify
72 """
73 etree = etree
74
77
91
105
106
110
115
122
132
137
143
151
162
166
171
178
188
193
199
207
218
220
221 value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
222 attrib={"gnu": "muh", "cat": "meeow",
223 "dog": "wuff"},
224 bird="tchilp", dog="grrr")
225 self.assertEquals(value.get("gnu"), "muh")
226 self.assertEquals(value.get("cat"), "meeow")
227 self.assertEquals(value.get("dog"), "grrr")
228 self.assertEquals(value.get("bird"), "tchilp")
229
241
243
244
245 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
246 attrib={"gnu": "muh", "cat": "meeow",
247 "dog": "wuff"},
248 bird="tchilp", dog="grrr")
249 value = objectify.DataElement(arg, _pytype="NoneType")
250 self.assert_(isinstance(value, objectify.NoneElement))
251 self.assertEquals(value.get(XML_SCHEMA_NIL_ATTR), "true")
252 self.assertEquals(value.text, None)
253 self.assertEquals(value.pyval, None)
254 for attr in arg.attrib:
255
256 self.assertEquals(value.get(attr), arg.get(attr))
257
259
260
261 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
262 attrib={"gnu": "muh", "cat": "meeow",
263 "dog": "wuff"},
264 bird="tchilp", dog="grrr")
265 value = objectify.DataElement(arg, _pytype="int")
266 self.assert_(isinstance(value, objectify.IntElement))
267 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
268 for attr in arg.attrib:
269 if not attr == objectify.PYTYPE_ATTRIBUTE:
270 self.assertEquals(value.get(attr), arg.get(attr))
271
273
274
275 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
276 attrib={"gnu": "muh", "cat": "meeow",
277 "dog": "wuff"},
278 bird="tchilp", dog="grrr")
279 value = objectify.DataElement(arg, _xsi="xsd:int")
280 self.assert_(isinstance(value, objectify.IntElement))
281 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
282 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
283 for attr in arg.attrib:
284 if not attr in [objectify.PYTYPE_ATTRIBUTE,
285 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
286 self.assertEquals(value.get(attr), arg.get(attr))
287
289
290
291 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
292 attrib={"gnu": "muh", "cat": "meeow",
293 "dog": "wuff"},
294 bird="tchilp", dog="grrr")
295 value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
296 self.assert_(isinstance(value, objectify.IntElement))
297 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
298 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
299 for attr in arg.attrib:
300 if not attr in [objectify.PYTYPE_ATTRIBUTE,
301 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
302 self.assertEquals(value.get(attr), arg.get(attr))
303
307
311
316
321
325
329
333
338
340 root = self.XML(xml_str)
341 self.assertEquals("0", getattr(root.c1, "{objectified}c2").text)
342 self.assertEquals("3", getattr(root.c1, "{otherNS}c2").text)
343
345 root = self.XML(xml_str)
346 self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
347 self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
348
350 for val in [
351 2, 2**32, 1.2, "Won't get fooled again",
352 _str("W\xf6n't get f\xf6\xf6led \xe4g\xe4in", 'ISO-8859-1'), True,
353 False, None]:
354 root = self.Element('root')
355 attrname = 'val'
356 setattr(root, attrname, val)
357 result = getattr(root, attrname)
358 self.assertEquals(val, result)
359 self.assertEquals(type(val), type(result.pyval))
360
367
374
376 root = self.XML(xml_str)
377 self.assertEquals(1, len(root.c1))
378
379 new_el = self.Element("test", myattr="5")
380 root.addattr("c1", new_el)
381 self.assertEquals(2, len(root.c1))
382 self.assertEquals(None, root.c1[0].get("myattr"))
383 self.assertEquals("5", root.c1[1].get("myattr"))
384
386 root = self.XML(xml_str)
387 self.assertEquals(1, len(root.c1))
388
389 new_el = self.Element("test")
390 self.etree.SubElement(new_el, "a", myattr="A")
391 self.etree.SubElement(new_el, "a", myattr="B")
392
393 root.addattr("c1", list(new_el.a))
394 self.assertEquals(3, len(root.c1))
395 self.assertEquals(None, root.c1[0].get("myattr"))
396 self.assertEquals("A", root.c1[1].get("myattr"))
397 self.assertEquals("B", root.c1[2].get("myattr"))
398
405
407 root = self.XML(xml_str)
408 self.assertEquals("0", root.c1.c2[0].text)
409 self.assertEquals("1", root.c1.c2[1].text)
410 self.assertEquals("2", root.c1.c2[2].text)
411 self.assertRaises(IndexError, operator.getitem, root.c1.c2, 3)
412
414 root = self.XML(xml_str)
415 self.assertEquals("0", root.c1.c2[0].text)
416 self.assertEquals("0", root.c1.c2[-3].text)
417 self.assertEquals("1", root.c1.c2[-2].text)
418 self.assertEquals("2", root.c1.c2[-1].text)
419 self.assertRaises(IndexError, operator.getitem, root.c1.c2, -4)
420
422 root = self.XML(xml_str)
423 self.assertEquals(1, len(root))
424 self.assertEquals(1, len(root.c1))
425 self.assertEquals(3, len(root.c1.c2))
426
435
441
451
456
461
462
463
465 root = self.XML("<root><c>c1</c><c>c2</c></root>")
466 self.assertEquals(["c1", "c2"],
467 [ c.text for c in root.c[:] ])
468
470 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
471 test_list = ["c1", "c2", "c3", "c4"]
472
473 self.assertEquals(test_list,
474 [ c.text for c in root.c[:] ])
475 self.assertEquals(test_list[1:2],
476 [ c.text for c in root.c[1:2] ])
477 self.assertEquals(test_list[-3:-1],
478 [ c.text for c in root.c[-3:-1] ])
479 self.assertEquals(test_list[-3:3],
480 [ c.text for c in root.c[-3:3] ])
481 self.assertEquals(test_list[-3000:3],
482 [ c.text for c in root.c[-3000:3] ])
483 self.assertEquals(test_list[-3:3000],
484 [ c.text for c in root.c[-3:3000] ])
485
487 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
488 test_list = ["c1", "c2", "c3", "c4"]
489
490 self.assertEquals(test_list,
491 [ c.text for c in root.c[:] ])
492 self.assertEquals(test_list[2:1:-1],
493 [ c.text for c in root.c[2:1:-1] ])
494 self.assertEquals(test_list[-1:-3:-1],
495 [ c.text for c in root.c[-1:-3:-1] ])
496 self.assertEquals(test_list[2:-3:-1],
497 [ c.text for c in root.c[2:-3:-1] ])
498 self.assertEquals(test_list[2:-3000:-1],
499 [ c.text for c in root.c[2:-3000:-1] ])
500
501
502
514
516 Element = self.Element
517 root = Element("root")
518 root.c = ["c1", "c2"]
519
520 c1 = root.c[0]
521 c2 = root.c[1]
522
523 self.assertEquals([c1,c2], list(root.c))
524 self.assertEquals(["c1", "c2"],
525 [ c.text for c in root.c ])
526
527 root2 = Element("root2")
528 root2.el = [ "test", "test" ]
529 self.assertEquals(["test", "test"],
530 [ el.text for el in root2.el ])
531
532 root.c = [ root2.el, root2.el ]
533 self.assertEquals(["test", "test"],
534 [ c.text for c in root.c ])
535 self.assertEquals(["test", "test"],
536 [ el.text for el in root2.el ])
537
538 root.c[:] = [ c1, c2, c2, c1 ]
539 self.assertEquals(["c1", "c2", "c2", "c1"],
540 [ c.text for c in root.c ])
541
543 Element = self.Element
544 root = Element("root")
545 l = ["c1", "c2", "c3", "c4"]
546 root.c = l
547
548 self.assertEquals(["c1", "c2", "c3", "c4"],
549 [ c.text for c in root.c ])
550 self.assertEquals(l,
551 [ c.text for c in root.c ])
552
553 new_slice = ["cA", "cB"]
554 l[1:2] = new_slice
555 root.c[1:2] = new_slice
556
557 self.assertEquals(["c1", "cA", "cB", "c3", "c4"], l)
558 self.assertEquals(["c1", "cA", "cB", "c3", "c4"],
559 [ c.text for c in root.c ])
560 self.assertEquals(l,
561 [ c.text for c in root.c ])
562
564 Element = self.Element
565 root = Element("root")
566 l = ["c1", "c2", "c3", "c4"]
567 root.c = l
568
569 self.assertEquals(["c1", "c2", "c3", "c4"],
570 [ c.text for c in root.c ])
571 self.assertEquals(l,
572 [ c.text for c in root.c ])
573
574 new_slice = ["cA", "cB"]
575 l[1:1] = new_slice
576 root.c[1:1] = new_slice
577
578 self.assertEquals(["c1", "cA", "cB", "c2", "c3", "c4"], l)
579 self.assertEquals(["c1", "cA", "cB", "c2", "c3", "c4"],
580 [ c.text for c in root.c ])
581 self.assertEquals(l,
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.assertEquals(["c1", "c2", "c3", "c4"],
591 [ c.text for c in root.c ])
592 self.assertEquals(l,
593 [ c.text for c in root.c ])
594
595 new_slice = ["cA", "cB"]
596 l[-2:-2] = new_slice
597 root.c[-2:-2] = new_slice
598
599 self.assertEquals(["c1", "c2", "cA", "cB", "c3", "c4"], l)
600 self.assertEquals(["c1", "c2", "cA", "cB", "c3", "c4"],
601 [ c.text for c in root.c ])
602 self.assertEquals(l,
603 [ c.text for c in root.c ])
604
612
614 Element = self.Element
615 root = Element("root")
616 l = ["c1", "c2", "c3", "c4"]
617 root.c = l
618
619 self.assertEquals(["c1", "c2", "c3", "c4"],
620 [ c.text for c in root.c ])
621 self.assertEquals(l,
622 [ c.text for c in root.c ])
623
624 new_slice = ["cA", "cB", "cC"]
625 self.assertRaises(
626 ValueError, operator.setitem,
627 l, slice(1,2,-1), new_slice)
628 self.assertRaises(
629 ValueError, operator.setitem,
630 root.c, slice(1,2,-1), new_slice)
631
633 Element = self.Element
634 root = Element("root")
635 l = ["c1", "c2", "c3", "c4"]
636 root.c = l
637
638 self.assertEquals(["c1", "c2", "c3", "c4"],
639 [ c.text for c in root.c ])
640 self.assertEquals(l,
641 [ c.text for c in root.c ])
642
643 new_slice = ["cA", "cB"]
644 l[-1:1:-1] = new_slice
645 root.c[-1:1:-1] = new_slice
646
647 self.assertEquals(["c1", "c2", "cB", "cA"], l)
648 self.assertEquals(["c1", "c2", "cB", "cA"],
649 [ c.text for c in root.c ])
650 self.assertEquals(l,
651 [ c.text for c in root.c ])
652
654 Element = self.Element
655 root = Element("root")
656 l = ["c1", "c2", "c3", "c4"]
657 root.c = l
658
659 self.assertEquals(["c1", "c2", "c3", "c4"],
660 [ c.text for c in root.c ])
661 self.assertEquals(l,
662 [ c.text for c in root.c ])
663
664 new_slice = ["cA", "cB"]
665 l[-1:-4:-2] = new_slice
666 root.c[-1:-4:-2] = new_slice
667
668 self.assertEquals(["c1", "cB", "c3", "cA"], l)
669 self.assertEquals(["c1", "cB", "c3", "cA"],
670 [ c.text for c in root.c ])
671 self.assertEquals(l,
672 [ c.text for c in root.c ])
673
674
675
683
691
693
694 Element = self.Element
695 root = Element("root")
696
697 root["text"] = "TEST"
698 self.assertEquals(["TEST"],
699 [ c.text for c in root["text"] ])
700
701 root["tail"] = "TEST"
702 self.assertEquals(["TEST"],
703 [ c.text for c in root["tail"] ])
704
705 root["pyval"] = "TEST"
706 self.assertEquals(["TEST"],
707 [ c.text for c in root["pyval"] ])
708
709 root["tag"] = "TEST"
710 self.assertEquals(["TEST"],
711 [ c.text for c in root["tag"] ])
712
720
722 XML = self.XML
723 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
724 self.assertEquals(2, len(root.findall(".//{X}b")))
725 self.assertEquals(3, len(root.findall(".//b")))
726 self.assertEquals(2, len(root.findall("b")))
727
735
750
756
758 Element = self.Element
759 SubElement = self.etree.SubElement
760 root = Element("{objectified}root")
761 root.bool = True
762 self.assertEquals(root.bool, True)
763 self.assertEquals(root.bool + root.bool, True + True)
764 self.assertEquals(True + root.bool, True + root.bool)
765 self.assertEquals(root.bool * root.bool, True * True)
766 self.assertEquals(int(root.bool), int(True))
767 self.assertEquals(hash(root.bool), hash(True))
768 self.assertEquals(complex(root.bool), complex(True))
769 self.assert_(isinstance(root.bool, objectify.BoolElement))
770
771 root.bool = False
772 self.assertEquals(root.bool, False)
773 self.assertEquals(root.bool + root.bool, False + False)
774 self.assertEquals(False + root.bool, False + root.bool)
775 self.assertEquals(root.bool * root.bool, False * False)
776 self.assertEquals(int(root.bool), int(False))
777 self.assertEquals(hash(root.bool), hash(False))
778 self.assertEquals(complex(root.bool), complex(False))
779 self.assert_(isinstance(root.bool, objectify.BoolElement))
780
789
796
803
810
812 Element = self.Element
813 SubElement = self.etree.SubElement
814 root = Element("{objectified}root")
815 root.s = "test"
816
817 self.assertEquals("test" * 5, root.s * 5)
818 self.assertEquals(5 * "test", 5 * root.s)
819
820 self.assertRaises(TypeError, operator.mul, root.s, "honk")
821 self.assertRaises(TypeError, operator.mul, "honk", root.s)
822
832
853
858
863
868
873
882
887
892
897
904
911
918
930
940
945
950
955
962
967
971
978
983
987
996
1005
1011
1020
1022 pyval = 1
1023 pytype = "NoneType"
1024 objclass = objectify.NoneElement
1025 value = objectify.DataElement(pyval, _pytype=pytype)
1026 self.assert_(isinstance(value, objclass),
1027 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1028 % (pyval, pytype, type(value), objclass))
1029 self.assertEquals(value.text, None)
1030 self.assertEquals(value.pyval, None)
1031
1033
1034 pyval = 1
1035 pytype = "none"
1036 objclass = objectify.NoneElement
1037 value = objectify.DataElement(pyval, _pytype=pytype)
1038 self.assert_(isinstance(value, objclass),
1039 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1040 % (pyval, pytype, type(value), objclass))
1041 self.assertEquals(value.text, None)
1042 self.assertEquals(value.pyval, None)
1043
1049 root = Element("{objectified}root")
1050 root.myfloat = MyFloat(5.5)
1051 self.assert_(isinstance(root.myfloat, objectify.FloatElement))
1052 self.assertEquals(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
1053
1055 class MyFloat(float):
1056 pass
1057 value = objectify.DataElement(MyFloat(5.5))
1058 self.assert_(isinstance(value, objectify.FloatElement))
1059 self.assertEquals(value, 5.5)
1060 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), None)
1061
1063 XML = self.XML
1064 root = XML('''\
1065 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1066 <b xsi:type="boolean">true</b>
1067 <b xsi:type="boolean">false</b>
1068 <b xsi:type="boolean">1</b>
1069 <b xsi:type="boolean">0</b>
1070
1071 <f xsi:type="float">5</f>
1072 <f xsi:type="double">5</f>
1073
1074 <s xsi:type="string">5</s>
1075 <s xsi:type="normalizedString">5</s>
1076 <s xsi:type="token">5</s>
1077 <s xsi:type="language">5</s>
1078 <s xsi:type="Name">5</s>
1079 <s xsi:type="NCName">5</s>
1080 <s xsi:type="ID">5</s>
1081 <s xsi:type="IDREF">5</s>
1082 <s xsi:type="ENTITY">5</s>
1083 <s xsi:type="NMTOKEN">5</s>
1084
1085 <l xsi:type="integer">5</l>
1086 <l xsi:type="nonPositiveInteger">5</l>
1087 <l xsi:type="negativeInteger">5</l>
1088 <l xsi:type="long">5</l>
1089 <l xsi:type="nonNegativeInteger">5</l>
1090 <l xsi:type="unsignedLong">5</l>
1091 <l xsi:type="unsignedInt">5</l>
1092 <l xsi:type="positiveInteger">5</l>
1093
1094 <i xsi:type="int">5</i>
1095 <i xsi:type="short">5</i>
1096 <i xsi:type="byte">5</i>
1097 <i xsi:type="unsignedShort">5</i>
1098 <i xsi:type="unsignedByte">5</i>
1099
1100 <n xsi:nil="true"/>
1101 </root>
1102 ''')
1103
1104 for b in root.b:
1105 self.assert_(isinstance(b, objectify.BoolElement))
1106 self.assertEquals(True, root.b[0])
1107 self.assertEquals(False, root.b[1])
1108 self.assertEquals(True, root.b[2])
1109 self.assertEquals(False, root.b[3])
1110
1111 for f in root.f:
1112 self.assert_(isinstance(f, objectify.FloatElement))
1113 self.assertEquals(5, f)
1114
1115 for s in root.s:
1116 self.assert_(isinstance(s, objectify.StringElement))
1117 self.assertEquals("5", s)
1118
1119 for i in root.i:
1120 self.assert_(isinstance(i, objectify.IntElement))
1121 self.assertEquals(5, i)
1122
1123 for l in root.l:
1124 self.assert_(isinstance(l, objectify.IntElement))
1125 self.assertEquals(5, i)
1126
1127 self.assert_(isinstance(root.n, objectify.NoneElement))
1128 self.assertEquals(None, root.n)
1129
1131 XML = self.XML
1132 root = XML('''\
1133 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1134 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1135 <b xsi:type="xsd:boolean">true</b>
1136 <b xsi:type="xsd:boolean">false</b>
1137 <b xsi:type="xsd:boolean">1</b>
1138 <b xsi:type="xsd:boolean">0</b>
1139
1140 <f xsi:type="xsd:float">5</f>
1141 <f xsi:type="xsd:double">5</f>
1142
1143 <s xsi:type="xsd:string">5</s>
1144 <s xsi:type="xsd:normalizedString">5</s>
1145 <s xsi:type="xsd:token">5</s>
1146 <s xsi:type="xsd:language">5</s>
1147 <s xsi:type="xsd:Name">5</s>
1148 <s xsi:type="xsd:NCName">5</s>
1149 <s xsi:type="xsd:ID">5</s>
1150 <s xsi:type="xsd:IDREF">5</s>
1151 <s xsi:type="xsd:ENTITY">5</s>
1152 <s xsi:type="xsd:NMTOKEN">5</s>
1153
1154 <l xsi:type="xsd:integer">5</l>
1155 <l xsi:type="xsd:nonPositiveInteger">5</l>
1156 <l xsi:type="xsd:negativeInteger">5</l>
1157 <l xsi:type="xsd:long">5</l>
1158 <l xsi:type="xsd:nonNegativeInteger">5</l>
1159 <l xsi:type="xsd:unsignedLong">5</l>
1160 <l xsi:type="xsd:unsignedInt">5</l>
1161 <l xsi:type="xsd:positiveInteger">5</l>
1162
1163 <i xsi:type="xsd:int">5</i>
1164 <i xsi:type="xsd:short">5</i>
1165 <i xsi:type="xsd:byte">5</i>
1166 <i xsi:type="xsd:unsignedShort">5</i>
1167 <i xsi:type="xsd:unsignedByte">5</i>
1168
1169 <n xsi:nil="true"/>
1170 </root>
1171 ''')
1172
1173 for b in root.b:
1174 self.assert_(isinstance(b, objectify.BoolElement))
1175 self.assertEquals(True, root.b[0])
1176 self.assertEquals(False, root.b[1])
1177 self.assertEquals(True, root.b[2])
1178 self.assertEquals(False, root.b[3])
1179
1180 for f in root.f:
1181 self.assert_(isinstance(f, objectify.FloatElement))
1182 self.assertEquals(5, f)
1183
1184 for s in root.s:
1185 self.assert_(isinstance(s, objectify.StringElement))
1186 self.assertEquals("5", s)
1187
1188 for i in root.i:
1189 self.assert_(isinstance(i, objectify.IntElement))
1190 self.assertEquals(5, i)
1191
1192 for l in root.l:
1193 self.assert_(isinstance(l, objectify.IntElement))
1194 self.assertEquals(5, l)
1195
1196 self.assert_(isinstance(root.n, objectify.NoneElement))
1197 self.assertEquals(None, root.n)
1198
1200 XML = self.XML
1201 root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
1202 strs = [ str(s) for s in root.b ]
1203 self.assertEquals(["why", "try"],
1204 strs)
1205
1232
1252
1253
1254
1278
1280 XML = self.XML
1281 root = XML(_bytes("""
1282 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1283 <b xsi:nil="true"></b><b xsi:nil="true"/>
1284 </root>"""))
1285 self.assert_(root.b[0] == root.b[1])
1286 self.assertFalse(root.b[0])
1287 self.assertEquals(root.b[0], None)
1288 self.assertEquals(None, root.b[0])
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1304
1311
1315
1317 XML = self.XML
1318 root = XML(_bytes('''\
1319 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1320 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1321 <b>5</b>
1322 <b>test</b>
1323 <c>1.1</c>
1324 <c>\uF8D2</c>
1325 <x>true</x>
1326 <n xsi:nil="true" />
1327 <n></n>
1328 <b xsi:type="double">5</b>
1329 <b xsi:type="float">5</b>
1330 <s xsi:type="string">23</s>
1331 <s py:pytype="str">42</s>
1332 <f py:pytype="float">300</f>
1333 <l py:pytype="long">2</l>
1334 <t py:pytype="TREE"></t>
1335 </a>
1336 '''))
1337 objectify.annotate(root)
1338
1339 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1340 for c in root.iterchildren() ]
1341 self.assertEquals("int", child_types[ 0])
1342 self.assertEquals("str", child_types[ 1])
1343 self.assertEquals("float", child_types[ 2])
1344 self.assertEquals("str", child_types[ 3])
1345 self.assertEquals("bool", child_types[ 4])
1346 self.assertEquals("NoneType", child_types[ 5])
1347 self.assertEquals(None, child_types[ 6])
1348 self.assertEquals("float", child_types[ 7])
1349 self.assertEquals("float", child_types[ 8])
1350 self.assertEquals("str", child_types[ 9])
1351 self.assertEquals("int", child_types[10])
1352 self.assertEquals("int", child_types[11])
1353 self.assertEquals("int", child_types[12])
1354 self.assertEquals(None, child_types[13])
1355
1356 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1357
1377
1379 XML = self.XML
1380 root = XML(_bytes('''\
1381 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1382 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1383 <b>5</b>
1384 <b>test</b>
1385 <c>1.1</c>
1386 <c>\uF8D2</c>
1387 <x>true</x>
1388 <n xsi:nil="true" />
1389 <n></n>
1390 <b xsi:type="double">5</b>
1391 <b xsi:type="float">5</b>
1392 <s xsi:type="string">23</s>
1393 <s py:pytype="str">42</s>
1394 <f py:pytype="float">300</f>
1395 <l py:pytype="long">2</l>
1396 <t py:pytype="TREE"></t>
1397 </a>
1398 '''))
1399 objectify.annotate(root, ignore_old=False)
1400
1401 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1402 for c in root.iterchildren() ]
1403 self.assertEquals("int", child_types[ 0])
1404 self.assertEquals("str", child_types[ 1])
1405 self.assertEquals("float", child_types[ 2])
1406 self.assertEquals("str", child_types[ 3])
1407 self.assertEquals("bool", child_types[ 4])
1408 self.assertEquals("NoneType", child_types[ 5])
1409 self.assertEquals(None, child_types[ 6])
1410 self.assertEquals("float", child_types[ 7])
1411 self.assertEquals("float", child_types[ 8])
1412 self.assertEquals("str", child_types[ 9])
1413 self.assertEquals("str", child_types[10])
1414 self.assertEquals("float", child_types[11])
1415 self.assertEquals("int", child_types[12])
1416 self.assertEquals(TREE_PYTYPE, child_types[13])
1417
1418 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1419
1421 XML = self.XML
1422 root = XML(_bytes('''\
1423 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1424 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1425 <b>5</b>
1426 <b>test</b>
1427 <c>1.1</c>
1428 <c>\uF8D2</c>
1429 <x>true</x>
1430 <n xsi:nil="true" />
1431 <n></n>
1432 <b xsi:type="double">5</b>
1433 <b xsi:type="float">5</b>
1434 <s xsi:type="string">23</s>
1435 <s py:pytype="str">42</s>
1436 <f py:pytype="float">300</f>
1437 <l py:pytype="long">2</l>
1438 <t py:pytype="TREE"></t>
1439 </a>
1440 '''))
1441 objectify.annotate(root, ignore_old=False, ignore_xsi=False,
1442 annotate_xsi=1, annotate_pytype=1)
1443
1444
1445 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1446 for c in root.iterchildren() ]
1447 self.assertEquals("int", child_types[ 0])
1448 self.assertEquals("str", child_types[ 1])
1449 self.assertEquals("float", child_types[ 2])
1450 self.assertEquals("str", child_types[ 3])
1451 self.assertEquals("bool", child_types[ 4])
1452 self.assertEquals("NoneType", child_types[ 5])
1453 self.assertEquals(None, child_types[ 6])
1454 self.assertEquals("float", child_types[ 7])
1455 self.assertEquals("float", child_types[ 8])
1456 self.assertEquals("str", child_types[ 9])
1457 self.assertEquals("str", child_types[10])
1458 self.assertEquals("float", child_types[11])
1459 self.assertEquals("int", child_types[12])
1460 self.assertEquals(TREE_PYTYPE, child_types[13])
1461
1462 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1463
1464 child_xsitypes = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1465 for c in root.iterchildren() ]
1466
1467
1468 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1469 for c in root.iterchildren() ]
1470 self.assertEquals("xsd:integer", child_types[ 0])
1471 self.assertEquals("xsd:string", child_types[ 1])
1472 self.assertEquals("xsd:double", child_types[ 2])
1473 self.assertEquals("xsd:string", child_types[ 3])
1474 self.assertEquals("xsd:boolean", child_types[ 4])
1475 self.assertEquals(None, child_types[ 5])
1476 self.assertEquals(None, child_types[ 6])
1477 self.assertEquals("xsd:double", child_types[ 7])
1478 self.assertEquals("xsd:float", child_types[ 8])
1479 self.assertEquals("xsd:string", child_types[ 9])
1480 self.assertEquals("xsd:string", child_types[10])
1481 self.assertEquals("xsd:double", child_types[11])
1482 self.assertEquals("xsd:integer", child_types[12])
1483 self.assertEquals(None, child_types[13])
1484
1485 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1486
1488 XML = self.XML
1489 root = XML(_bytes('''\
1490 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1491 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1492 <b>5</b>
1493 <b>test</b>
1494 <c>1.1</c>
1495 <c>\uF8D2</c>
1496 <x>true</x>
1497 <n xsi:nil="true" />
1498 <n></n>
1499 <b xsi:type="double">5</b>
1500 <b xsi:type="float">5</b>
1501 <s xsi:type="string">23</s>
1502 <s py:pytype="str">42</s>
1503 <f py:pytype="float">300</f>
1504 <l py:pytype="long">2</l>
1505 <t py:pytype="TREE"></t>
1506 </a>
1507 '''))
1508 objectify.xsiannotate(root, ignore_old=False)
1509
1510 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1511 for c in root.iterchildren() ]
1512 self.assertEquals("xsd:integer", child_types[ 0])
1513 self.assertEquals("xsd:string", child_types[ 1])
1514 self.assertEquals("xsd:double", child_types[ 2])
1515 self.assertEquals("xsd:string", child_types[ 3])
1516 self.assertEquals("xsd:boolean", child_types[ 4])
1517 self.assertEquals(None, child_types[ 5])
1518 self.assertEquals(None, child_types[ 6])
1519 self.assertEquals("xsd:double", child_types[ 7])
1520 self.assertEquals("xsd:float", child_types[ 8])
1521 self.assertEquals("xsd:string", child_types[ 9])
1522 self.assertEquals("xsd:string", child_types[10])
1523 self.assertEquals("xsd:double", child_types[11])
1524 self.assertEquals("xsd:integer", child_types[12])
1525 self.assertEquals(None, child_types[13])
1526
1528 XML = self.XML
1529 root = XML(_bytes('''\
1530 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1531 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1532 <b>5</b>
1533 <b>test</b>
1534 <c>1.1</c>
1535 <c>\uF8D2</c>
1536 <x>true</x>
1537 <n xsi:nil="true" />
1538 <n></n>
1539 <b xsi:type="double">5</b>
1540 <b xsi:type="float">5</b>
1541 <s xsi:type="string">23</s>
1542 <s py:pytype="str">42</s>
1543 <f py:pytype="float">300</f>
1544 <l py:pytype="long">2</l>
1545 <t py:pytype="TREE"></t>
1546 </a>
1547 '''))
1548 objectify.pyannotate(root, ignore_old=True)
1549
1550 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1551 for c in root.iterchildren() ]
1552 self.assertEquals("int", child_types[ 0])
1553 self.assertEquals("str", child_types[ 1])
1554 self.assertEquals("float", child_types[ 2])
1555 self.assertEquals("str", child_types[ 3])
1556 self.assertEquals("bool", child_types[ 4])
1557 self.assertEquals("NoneType", child_types[ 5])
1558 self.assertEquals(None, child_types[ 6])
1559 self.assertEquals("float", child_types[ 7])
1560 self.assertEquals("float", child_types[ 8])
1561 self.assertEquals("str", child_types[ 9])
1562 self.assertEquals("int", child_types[10])
1563 self.assertEquals("int", child_types[11])
1564 self.assertEquals("int", child_types[12])
1565 self.assertEquals(None, child_types[13])
1566
1567 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1568
1588
1590 XML = self.XML
1591 root = XML('''\
1592 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1593 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1594 <b>5</b>
1595 <b>test</b>
1596 <c>1.1</c>
1597 <c>\uF8D2</c>
1598 <x>true</x>
1599 <n xsi:nil="true" />
1600 <n></n>
1601 <b xsi:type="double">5</b>
1602 <b xsi:type="float">5</b>
1603 <s xsi:type="string">23</s>
1604 <s py:pytype="str">42</s>
1605 <f py:pytype="float">300</f>
1606 <l py:pytype="long">2</l>
1607 <t py:pytype="TREE"></t>
1608 </a>
1609 ''')
1610 objectify.pyannotate(root)
1611
1612 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1613 for c in root.iterchildren() ]
1614 self.assertEquals("int", child_types[ 0])
1615 self.assertEquals("str", child_types[ 1])
1616 self.assertEquals("float", child_types[ 2])
1617 self.assertEquals("str", child_types[ 3])
1618 self.assertEquals("bool", child_types[ 4])
1619 self.assertEquals("NoneType", child_types[ 5])
1620 self.assertEquals(None, child_types[ 6])
1621 self.assertEquals("float", child_types[ 7])
1622 self.assertEquals("float", child_types[ 8])
1623 self.assertEquals("str", child_types[ 9])
1624 self.assertEquals("str", child_types[10])
1625 self.assertEquals("float", child_types[11])
1626 self.assertEquals("int", child_types[12])
1627 self.assertEquals(TREE_PYTYPE, child_types[13])
1628
1629 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1630
1632 XML = self.XML
1633 root = XML(_bytes('''\
1634 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1635 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1636 <b>5</b>
1637 <b>test</b>
1638 <c>1.1</c>
1639 <c>\uF8D2</c>
1640 <x>true</x>
1641 <n xsi:nil="true" />
1642 <n></n>
1643 <b xsi:type="double">5</b>
1644 <b xsi:type="float">5</b>
1645 <s xsi:type="string">23</s>
1646 <s py:pytype="str">42</s>
1647 <f py:pytype="float">300</f>
1648 <l py:pytype="long">2</l>
1649 <t py:pytype="TREE"></t>
1650 </a>
1651 '''))
1652 objectify.xsiannotate(root, ignore_old=True)
1653
1654 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1655 for c in root.iterchildren() ]
1656 self.assertEquals("xsd:integer", child_types[ 0])
1657 self.assertEquals("xsd:string", child_types[ 1])
1658 self.assertEquals("xsd:double", child_types[ 2])
1659 self.assertEquals("xsd:string", child_types[ 3])
1660 self.assertEquals("xsd:boolean", child_types[ 4])
1661 self.assertEquals(None, child_types[ 5])
1662 self.assertEquals(None, child_types[ 6])
1663 self.assertEquals("xsd:integer", child_types[ 7])
1664 self.assertEquals("xsd:integer", child_types[ 8])
1665 self.assertEquals("xsd:integer", child_types[ 9])
1666 self.assertEquals("xsd:string", child_types[10])
1667 self.assertEquals("xsd:double", child_types[11])
1668 self.assertEquals("xsd:integer", child_types[12])
1669 self.assertEquals(None, child_types[13])
1670
1671 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1672
1674 XML = self.XML
1675 root = XML(_bytes('''\
1676 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1677 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1678 <b>5</b>
1679 <b>test</b>
1680 <c>1.1</c>
1681 <c>\uF8D2</c>
1682 <x>true</x>
1683 <n xsi:nil="true" />
1684 <n></n>
1685 <b xsi:type="double">5</b>
1686 <b xsi:type="float">5</b>
1687 <s xsi:type="string">23</s>
1688 <s py:pytype="str">42</s>
1689 <f py:pytype="float">300</f>
1690 <l py:pytype="long">2</l>
1691 <t py:pytype="TREE"></t>
1692 </a>
1693 '''))
1694 objectify.deannotate(root)
1695
1696 for c in root.getiterator():
1697 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1698 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1699
1700 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1701
1703 XML = self.XML
1704 root = XML(_bytes('''\
1705 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1706 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1707 <b>5</b>
1708 <b>test</b>
1709 <c>1.1</c>
1710 <c>\uF8D2</c>
1711 <x>true</x>
1712 <n xsi:nil="true" />
1713 <n></n>
1714 <b xsi:type="double">5</b>
1715 <b xsi:type="float">5</b>
1716 <s xsi:type="string">23</s>
1717 <s py:pytype="str">42</s>
1718 <f py:pytype="float">300</f>
1719 <l py:pytype="long">2</l>
1720 <t py:pytype="TREE"></t>
1721 </a>
1722 '''))
1723 objectify.annotate(
1724 root, ignore_old=False, ignore_xsi=False, annotate_xsi=True,
1725 empty_pytype='str', empty_type='string')
1726 objectify.deannotate(root, pytype=False, xsi=False, xsi_nil=True)
1727
1728 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1729 for c in root.iterchildren() ]
1730 self.assertEquals("xsd:integer", child_types[ 0])
1731 self.assertEquals("xsd:string", child_types[ 1])
1732 self.assertEquals("xsd:double", child_types[ 2])
1733 self.assertEquals("xsd:string", child_types[ 3])
1734 self.assertEquals("xsd:boolean", child_types[ 4])
1735 self.assertEquals(None, child_types[ 5])
1736 self.assertEquals("xsd:string", child_types[ 6])
1737 self.assertEquals("xsd:double", child_types[ 7])
1738 self.assertEquals("xsd:float", child_types[ 8])
1739 self.assertEquals("xsd:string", child_types[ 9])
1740 self.assertEquals("xsd:string", child_types[10])
1741 self.assertEquals("xsd:double", child_types[11])
1742 self.assertEquals("xsd:integer", child_types[12])
1743 self.assertEquals(None, child_types[13])
1744
1745 self.assertEquals(None, root.n.get(XML_SCHEMA_NIL_ATTR))
1746
1747 for c in root.iterchildren():
1748 self.assertNotEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1749
1750 if (c.get(objectify.PYTYPE_ATTRIBUTE) not in [TREE_PYTYPE,
1751 "NoneType"]):
1752 self.assertNotEquals(
1753 None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1754
1756 XML = self.XML
1757 root = XML(_bytes('''\
1758 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1759 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1760 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1761 <b>5</b>
1762 <b>test</b>
1763 <c>1.1</c>
1764 <c>\uF8D2</c>
1765 <x>true</x>
1766 <n xsi:nil="true" />
1767 <n></n>
1768 <b xsi:type="xsd:double">5</b>
1769 <b xsi:type="xsd:float">5</b>
1770 <s xsi:type="xsd:string">23</s>
1771 <s py:pytype="str">42</s>
1772 <f py:pytype="float">300</f>
1773 <l py:pytype="long">2</l>
1774 <t py:pytype="TREE"></t>
1775 </a>
1776 '''))
1777 objectify.annotate(root)
1778 objectify.deannotate(root, pytype=False)
1779
1780 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1781 for c in root.iterchildren() ]
1782 self.assertEquals("int", child_types[ 0])
1783 self.assertEquals("str", child_types[ 1])
1784 self.assertEquals("float", child_types[ 2])
1785 self.assertEquals("str", child_types[ 3])
1786 self.assertEquals("bool", child_types[ 4])
1787 self.assertEquals("NoneType", child_types[ 5])
1788 self.assertEquals(None, child_types[ 6])
1789 self.assertEquals("float", child_types[ 7])
1790 self.assertEquals("float", child_types[ 8])
1791 self.assertEquals("str", child_types[ 9])
1792 self.assertEquals("int", child_types[10])
1793 self.assertEquals("int", child_types[11])
1794 self.assertEquals("int", child_types[12])
1795 self.assertEquals(None, child_types[13])
1796
1797 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1798
1799 for c in root.getiterator():
1800 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1801
1803 XML = self.XML
1804 root = XML(_bytes('''\
1805 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1806 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1807 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1808 <b xsi:type="xsd:int">5</b>
1809 <b xsi:type="xsd:string">test</b>
1810 <c xsi:type="xsd:float">1.1</c>
1811 <c xsi:type="xsd:string">\uF8D2</c>
1812 <x xsi:type="xsd:boolean">true</x>
1813 <n xsi:nil="true" />
1814 <n></n>
1815 <b xsi:type="xsd:double">5</b>
1816 <b xsi:type="xsd:float">5</b>
1817 <s xsi:type="xsd:string">23</s>
1818 <s xsi:type="xsd:string">42</s>
1819 <f xsi:type="xsd:float">300</f>
1820 <l xsi:type="xsd:long">2</l>
1821 <t py:pytype="TREE"></t>
1822 </a>
1823 '''))
1824 objectify.annotate(root)
1825 objectify.deannotate(root, xsi=False)
1826
1827 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1828 for c in root.iterchildren() ]
1829 self.assertEquals("xsd:int", child_types[ 0])
1830 self.assertEquals("xsd:string", child_types[ 1])
1831 self.assertEquals("xsd:float", child_types[ 2])
1832 self.assertEquals("xsd:string", child_types[ 3])
1833 self.assertEquals("xsd:boolean", child_types[ 4])
1834 self.assertEquals(None, child_types[ 5])
1835 self.assertEquals(None, child_types[ 6])
1836 self.assertEquals("xsd:double", child_types[ 7])
1837 self.assertEquals("xsd:float", child_types[ 8])
1838 self.assertEquals("xsd:string", child_types[ 9])
1839 self.assertEquals("xsd:string", child_types[10])
1840 self.assertEquals("xsd:float", child_types[11])
1841 self.assertEquals("xsd:long", child_types[12])
1842 self.assertEquals(None, child_types[13])
1843
1844 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1845
1846 for c in root.getiterator():
1847 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1848
1850 XML = self.XML
1851
1852 xml = _bytes('''\
1853 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1854 <b>5</b>
1855 <b>test</b>
1856 <c>1.1</c>
1857 <c>\uF8D2</c>
1858 <x>true</x>
1859 <n xsi:nil="true" />
1860 <n></n>
1861 <b xsi:type="double">5</b>
1862 </a>
1863 ''')
1864
1865 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1866 objectify.set_pytype_attribute_tag("{TEST}test")
1867
1868 root = XML(xml)
1869 objectify.annotate(root)
1870
1871 attribs = root.xpath("//@py:%s" % pytype_name,
1872 namespaces={"py" : pytype_ns})
1873 self.assertEquals(0, len(attribs))
1874 attribs = root.xpath("//@py:test",
1875 namespaces={"py" : "TEST"})
1876 self.assertEquals(7, len(attribs))
1877
1878 objectify.set_pytype_attribute_tag()
1879 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1880
1881 self.assertNotEqual("test", pytype_ns.lower())
1882 self.assertNotEqual("test", pytype_name.lower())
1883
1884 root = XML(xml)
1885 attribs = root.xpath("//@py:%s" % pytype_name,
1886 namespaces={"py" : pytype_ns})
1887 self.assertEquals(0, len(attribs))
1888
1889 objectify.annotate(root)
1890 attribs = root.xpath("//@py:%s" % pytype_name,
1891 namespaces={"py" : pytype_ns})
1892 self.assertEquals(7, len(attribs))
1893
1901
1902 def checkMyType(s):
1903 return True
1904
1905 pytype = objectify.PyType("mytype", checkMyType, NewType)
1906 self.assert_(pytype not in objectify.getRegisteredTypes())
1907 pytype.register()
1908 self.assert_(pytype in objectify.getRegisteredTypes())
1909 pytype.unregister()
1910 self.assert_(pytype not in objectify.getRegisteredTypes())
1911
1912 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
1913 self.assertEquals(pytype, objectify.getRegisteredTypes()[0])
1914 pytype.unregister()
1915
1916 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
1917 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
1918 pytype.unregister()
1919
1920 self.assertRaises(ValueError, pytype.register,
1921 before = [objectify.getRegisteredTypes()[0].name],
1922 after = [objectify.getRegisteredTypes()[1].name])
1923
1925 from datetime import datetime
1926 def parse_date(value):
1927 if len(value) != 14:
1928 raise ValueError(value)
1929 Y = int(value[0:4])
1930 M = int(value[4:6])
1931 D = int(value[6:8])
1932 h = int(value[8:10])
1933 m = int(value[10:12])
1934 s = int(value[12:14])
1935 return datetime(Y, M, D, h, m, s)
1936
1937 def stringify_date(date):
1938 return date.strftime("%Y%m%d%H%M%S")
1939
1940 class DatetimeElement(objectify.ObjectifiedDataElement):
1941 def pyval(self):
1942 return parse_date(self.text)
1943 pyval = property(pyval)
1944
1945 datetime_type = objectify.PyType(
1946 "datetime", parse_date, DatetimeElement, stringify_date)
1947 datetime_type.xmlSchemaTypes = "dateTime"
1948 datetime_type.register()
1949
1950 NAMESPACE = "http://foo.net/xmlns"
1951 NAMESPACE_MAP = {'ns': NAMESPACE}
1952
1953 r = objectify.Element("{%s}root" % NAMESPACE, nsmap=NAMESPACE_MAP)
1954 time = datetime.now()
1955 r.date = time
1956
1957 self.assert_(isinstance(r.date, DatetimeElement))
1958 self.assert_(isinstance(r.date.pyval, datetime))
1959
1960 self.assertEquals(r.date.pyval, parse_date(stringify_date(time)))
1961 self.assertEquals(r.date.text, stringify_date(time))
1962
1963 r.date = objectify.E.date(time)
1964
1965 self.assert_(isinstance(r.date, DatetimeElement))
1966 self.assert_(isinstance(r.date.pyval, datetime))
1967
1968 self.assertEquals(r.date.pyval, parse_date(stringify_date(time)))
1969 self.assertEquals(r.date.text, stringify_date(time))
1970
1976
1982
1987
1996
2003
2011
2014
2017
2036
2041
2046
2051
2056
2076
2078 root = self.XML(xml_str)
2079 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
2080 self.assertEquals(root.c1.c2.text, path(root).text)
2081
2082 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
2083 self.assertEquals(root.c1.c2[2].text, path(root).text)
2084
2085 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
2086 self.assertEquals(root.c1.c2[2].text, path(root).text)
2087
2088 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
2089 self.assertEquals(root.c1.c2[-1].text, path(root).text)
2090
2091 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
2092 self.assertEquals(root.c1.c2[-3].text, path(root).text)
2093
2095 self.assertRaises(ValueError, objectify.ObjectPath,
2096 "root.c1[0].c2[-1-2]")
2097 self.assertRaises(ValueError, objectify.ObjectPath,
2098 ['root', 'c1[0]', 'c2[-1-2]'])
2099
2100 self.assertRaises(ValueError, objectify.ObjectPath,
2101 "root[2].c1.c2")
2102 self.assertRaises(ValueError, objectify.ObjectPath,
2103 ['root[2]', 'c1', 'c2'])
2104
2105 self.assertRaises(ValueError, objectify.ObjectPath,
2106 [])
2107 self.assertRaises(ValueError, objectify.ObjectPath,
2108 ['', '', ''])
2109
2111 root = self.XML(xml_str)
2112 path = objectify.ObjectPath("root.c1[9999].c2")
2113 self.assertRaises(AttributeError, path, root)
2114
2115 path = objectify.ObjectPath("root.c1[0].c2[9999]")
2116 self.assertRaises(AttributeError, path, root)
2117
2118 path = objectify.ObjectPath(".c1[9999].c2[0]")
2119 self.assertRaises(AttributeError, path, root)
2120
2121 path = objectify.ObjectPath("root.c1[-2].c2")
2122 self.assertRaises(AttributeError, path, root)
2123
2124 path = objectify.ObjectPath("root.c1[0].c2[-4]")
2125 self.assertRaises(AttributeError, path, root)
2126
2140
2142 root = self.XML(xml_str)
2143 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
2144 self.assertEquals(root.c1.c2.text, path.find(root).text)
2145 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
2146 self.assertEquals(root.c1.c2.text, path.find(root).text)
2147 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
2148 self.assertEquals(root.c1.c2.text, path.find(root).text)
2149 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
2150 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
2151 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
2152 self.assertEquals(root.c1.c2.text, path.find(root).text)
2153 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
2154 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
2155 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
2156 self.assertEquals(getattr(root.c1, '{otherNS}c2').text,
2157 path.find(root).text)
2158
2171
2186
2198
2212
2214 root = self.XML(xml_str)
2215 path = objectify.ObjectPath( "root.c1.c99" )
2216 self.assertRaises(AttributeError, path.find, root)
2217
2218 new_el = self.Element("{objectified}test")
2219 new_el.a = ["TEST1", "TEST2"]
2220 new_el.a[0].set("myattr", "ATTR1")
2221 new_el.a[1].set("myattr", "ATTR2")
2222
2223 path.setattr(root, list(new_el.a))
2224
2225 self.assertEquals(2, len(root.c1.c99))
2226 self.assertEquals("ATTR1", root.c1.c99[0].get("myattr"))
2227 self.assertEquals("TEST1", root.c1.c99[0].text)
2228 self.assertEquals("ATTR2", root.c1.c99[1].get("myattr"))
2229 self.assertEquals("TEST2", root.c1.c99[1].text)
2230 self.assertEquals("TEST1", path(root).text)
2231
2240
2254
2266
2280
2295
2297 root = self.XML(xml_str)
2298 self.assertEquals(
2299 ['{objectified}root', '{objectified}root.c1',
2300 '{objectified}root.c1.c2',
2301 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
2302 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
2303 root.descendantpaths())
2304
2306 root = self.XML(xml_str)
2307 self.assertEquals(
2308 ['{objectified}c1', '{objectified}c1.c2',
2309 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
2310 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
2311 root.c1.descendantpaths())
2312
2314 root = self.XML(xml_str)
2315 self.assertEquals(
2316 ['root.{objectified}c1', 'root.{objectified}c1.c2',
2317 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
2318 'root.{objectified}c1.{otherNS}c2',
2319 'root.{objectified}c1.{}c2'],
2320 root.c1.descendantpaths('root'))
2321
2333
2346
2350
2354
2358
2364
2369
2371 import pickle
2372 if isinstance(stringOrElt, (etree._Element, etree._ElementTree)):
2373 elt = stringOrElt
2374 else:
2375 elt = self.XML(stringOrElt)
2376 out = BytesIO()
2377 pickle.dump(elt, out)
2378
2379 new_elt = pickle.loads(out.getvalue())
2380 self.assertEquals(
2381 etree.tostring(new_elt),
2382 etree.tostring(elt))
2383
2384
2385
2390
2395
2400
2405
2410
2415
2420
2425
2427 E = objectify.E
2428 DataElement = objectify.DataElement
2429 root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
2430 DataElement(2.0))
2431 self.assert_(isinstance(root, objectify.ObjectifiedElement))
2432 self.assertEquals(root.text, "text")
2433 self.assert_(isinstance(root.sub, objectify.ObjectifiedElement))
2434 self.assertEquals(root.sub.tail, "tail")
2435 self.assert_(isinstance(root.sub.subsub, objectify.StringElement))
2436 self.assertEquals(len(root.value), 2)
2437 self.assert_(isinstance(root.value[0], objectify.IntElement))
2438 self.assert_(isinstance(root.value[1], objectify.FloatElement))
2439
2446
2447 attr = Attribute()
2448 self.assertEquals(attr.text, None)
2449 self.assertEquals(attr.get("datatype"), "TYPE")
2450 self.assertEquals(attr.get("range"), "0.,1.")
2451
2456
2463
2468
2474
2476 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2477 self.assertEquals(root.base, "http://no/such/url")
2478 self.assertEquals(
2479 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2480 root.base = "https://secret/url"
2481 self.assertEquals(root.base, "https://secret/url")
2482 self.assertEquals(
2483 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2484 "https://secret/url")
2485
2487 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2488 self.assertEquals(root.base, "http://no/such/url")
2489 self.assertEquals(
2490 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2491 root.set('{http://www.w3.org/XML/1998/namespace}base',
2492 "https://secret/url")
2493 self.assertEquals(root.base, "https://secret/url")
2494 self.assertEquals(
2495 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2496 "https://secret/url")
2497
2499 XML = self.XML
2500
2501 xml = _bytes('''\
2502 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2503 <i>5</i>
2504 <i>-5</i>
2505 <l>4294967296</l>
2506 <l>-4294967296</l>
2507 <f>1.1</f>
2508 <b>true</b>
2509 <b>false</b>
2510 <s>Strange things happen, where strings collide</s>
2511 <s>True</s>
2512 <s>False</s>
2513 <s>t</s>
2514 <s>f</s>
2515 <s></s>
2516 <s>None</s>
2517 <n xsi:nil="true" />
2518 </root>
2519 ''')
2520 root = XML(xml)
2521
2522 for i in root.i:
2523 self.assert_(isinstance(i, objectify.IntElement))
2524 for l in root.l:
2525 self.assert_(isinstance(l, objectify.IntElement))
2526 for f in root.f:
2527 self.assert_(isinstance(f, objectify.FloatElement))
2528 for b in root.b:
2529 self.assert_(isinstance(b, objectify.BoolElement))
2530 self.assertEquals(True, root.b[0])
2531 self.assertEquals(False, root.b[1])
2532 for s in root.s:
2533 self.assert_(isinstance(s, objectify.StringElement))
2534 self.assert_(isinstance(root.n, objectify.NoneElement))
2535 self.assertEquals(None, root.n)
2536
2538 suite = unittest.TestSuite()
2539 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
2540 suite.addTests(doctest.DocTestSuite(objectify))
2541 if sys.version_info >= (2,4):
2542 suite.addTests(
2543 [make_doctest('../../../doc/objectify.txt')])
2544 return suite
2545
2546 if __name__ == '__main__':
2547 print('to test use test.py %s' % __file__)
2548