ยปCore Development>Code coverage>Lib/test/test_minidom.py

Python code coverage for Lib/test/test_minidom.py

#countcontent
1n/a# test for xml.dom.minidom
2n/a
3n/aimport copy
4n/aimport pickle
5n/afrom test.support import findfile
6n/aimport unittest
7n/a
8n/aimport xml.dom.minidom
9n/a
10n/afrom xml.dom.minidom import parse, Node, Document, parseString
11n/afrom xml.dom.minidom import getDOMImplementation
12n/a
13n/a
14n/atstfile = findfile("test.xml", subdir="xmltestdata")
15n/asample = ("<?xml version='1.0' encoding='us-ascii'?>\n"
16n/a "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
17n/a " 'http://xml.python.org/system' [\n"
18n/a " <!ELEMENT e EMPTY>\n"
19n/a " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
20n/a "]><doc attr='value'> text\n"
21n/a "<?pi sample?> <!-- comment --> <e/> </doc>")
22n/a
23n/a# The tests of DocumentType importing use these helpers to construct
24n/a# the documents to work with, since not all DOM builders actually
25n/a# create the DocumentType nodes.
26n/adef create_doc_without_doctype(doctype=None):
27n/a return getDOMImplementation().createDocument(None, "doc", doctype)
28n/a
29n/adef create_nonempty_doctype():
30n/a doctype = getDOMImplementation().createDocumentType("doc", None, None)
31n/a doctype.entities._seq = []
32n/a doctype.notations._seq = []
33n/a notation = xml.dom.minidom.Notation("my-notation", None,
34n/a "http://xml.python.org/notations/my")
35n/a doctype.notations._seq.append(notation)
36n/a entity = xml.dom.minidom.Entity("my-entity", None,
37n/a "http://xml.python.org/entities/my",
38n/a "my-notation")
39n/a entity.version = "1.0"
40n/a entity.encoding = "utf-8"
41n/a entity.actualEncoding = "us-ascii"
42n/a doctype.entities._seq.append(entity)
43n/a return doctype
44n/a
45n/adef create_doc_with_doctype():
46n/a doctype = create_nonempty_doctype()
47n/a doc = create_doc_without_doctype(doctype)
48n/a doctype.entities.item(0).ownerDocument = doc
49n/a doctype.notations.item(0).ownerDocument = doc
50n/a return doc
51n/a
52n/aclass MinidomTest(unittest.TestCase):
53n/a def confirm(self, test, testname = "Test"):
54n/a self.assertTrue(test, testname)
55n/a
56n/a def checkWholeText(self, node, s):
57n/a t = node.wholeText
58n/a self.confirm(t == s, "looking for %r, found %r" % (s, t))
59n/a
60n/a def testDocumentAsyncAttr(self):
61n/a doc = Document()
62n/a self.assertFalse(doc.async_)
63n/a with self.assertWarns(DeprecationWarning):
64n/a self.assertFalse(getattr(doc, 'async', True))
65n/a with self.assertWarns(DeprecationWarning):
66n/a setattr(doc, 'async', True)
67n/a with self.assertWarns(DeprecationWarning):
68n/a self.assertTrue(getattr(doc, 'async', False))
69n/a self.assertTrue(doc.async_)
70n/a
71n/a self.assertFalse(Document.async_)
72n/a with self.assertWarns(DeprecationWarning):
73n/a self.assertFalse(getattr(Document, 'async', True))
74n/a
75n/a def testParseFromBinaryFile(self):
76n/a with open(tstfile, 'rb') as file:
77n/a dom = parse(file)
78n/a dom.unlink()
79n/a self.confirm(isinstance(dom, Document))
80n/a
81n/a def testParseFromTextFile(self):
82n/a with open(tstfile, 'r', encoding='iso-8859-1') as file:
83n/a dom = parse(file)
84n/a dom.unlink()
85n/a self.confirm(isinstance(dom, Document))
86n/a
87n/a def testGetElementsByTagName(self):
88n/a dom = parse(tstfile)
89n/a self.confirm(dom.getElementsByTagName("LI") == \
90n/a dom.documentElement.getElementsByTagName("LI"))
91n/a dom.unlink()
92n/a
93n/a def testInsertBefore(self):
94n/a dom = parseString("<doc><foo/></doc>")
95n/a root = dom.documentElement
96n/a elem = root.childNodes[0]
97n/a nelem = dom.createElement("element")
98n/a root.insertBefore(nelem, elem)
99n/a self.confirm(len(root.childNodes) == 2
100n/a and root.childNodes.length == 2
101n/a and root.childNodes[0] is nelem
102n/a and root.childNodes.item(0) is nelem
103n/a and root.childNodes[1] is elem
104n/a and root.childNodes.item(1) is elem
105n/a and root.firstChild is nelem
106n/a and root.lastChild is elem
107n/a and root.toxml() == "<doc><element/><foo/></doc>"
108n/a , "testInsertBefore -- node properly placed in tree")
109n/a nelem = dom.createElement("element")
110n/a root.insertBefore(nelem, None)
111n/a self.confirm(len(root.childNodes) == 3
112n/a and root.childNodes.length == 3
113n/a and root.childNodes[1] is elem
114n/a and root.childNodes.item(1) is elem
115n/a and root.childNodes[2] is nelem
116n/a and root.childNodes.item(2) is nelem
117n/a and root.lastChild is nelem
118n/a and nelem.previousSibling is elem
119n/a and root.toxml() == "<doc><element/><foo/><element/></doc>"
120n/a , "testInsertBefore -- node properly placed in tree")
121n/a nelem2 = dom.createElement("bar")
122n/a root.insertBefore(nelem2, nelem)
123n/a self.confirm(len(root.childNodes) == 4
124n/a and root.childNodes.length == 4
125n/a and root.childNodes[2] is nelem2
126n/a and root.childNodes.item(2) is nelem2
127n/a and root.childNodes[3] is nelem
128n/a and root.childNodes.item(3) is nelem
129n/a and nelem2.nextSibling is nelem
130n/a and nelem.previousSibling is nelem2
131n/a and root.toxml() ==
132n/a "<doc><element/><foo/><bar/><element/></doc>"
133n/a , "testInsertBefore -- node properly placed in tree")
134n/a dom.unlink()
135n/a
136n/a def _create_fragment_test_nodes(self):
137n/a dom = parseString("<doc/>")
138n/a orig = dom.createTextNode("original")
139n/a c1 = dom.createTextNode("foo")
140n/a c2 = dom.createTextNode("bar")
141n/a c3 = dom.createTextNode("bat")
142n/a dom.documentElement.appendChild(orig)
143n/a frag = dom.createDocumentFragment()
144n/a frag.appendChild(c1)
145n/a frag.appendChild(c2)
146n/a frag.appendChild(c3)
147n/a return dom, orig, c1, c2, c3, frag
148n/a
149n/a def testInsertBeforeFragment(self):
150n/a dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
151n/a dom.documentElement.insertBefore(frag, None)
152n/a self.confirm(tuple(dom.documentElement.childNodes) ==
153n/a (orig, c1, c2, c3),
154n/a "insertBefore(<fragment>, None)")
155n/a frag.unlink()
156n/a dom.unlink()
157n/a
158n/a dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
159n/a dom.documentElement.insertBefore(frag, orig)
160n/a self.confirm(tuple(dom.documentElement.childNodes) ==
161n/a (c1, c2, c3, orig),
162n/a "insertBefore(<fragment>, orig)")
163n/a frag.unlink()
164n/a dom.unlink()
165n/a
166n/a def testAppendChild(self):
167n/a dom = parse(tstfile)
168n/a dom.documentElement.appendChild(dom.createComment("Hello"))
169n/a self.confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
170n/a self.confirm(dom.documentElement.childNodes[-1].data == "Hello")
171n/a dom.unlink()
172n/a
173n/a def testAppendChildFragment(self):
174n/a dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
175n/a dom.documentElement.appendChild(frag)
176n/a self.confirm(tuple(dom.documentElement.childNodes) ==
177n/a (orig, c1, c2, c3),
178n/a "appendChild(<fragment>)")
179n/a frag.unlink()
180n/a dom.unlink()
181n/a
182n/a def testReplaceChildFragment(self):
183n/a dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
184n/a dom.documentElement.replaceChild(frag, orig)
185n/a orig.unlink()
186n/a self.confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
187n/a "replaceChild(<fragment>)")
188n/a frag.unlink()
189n/a dom.unlink()
190n/a
191n/a def testLegalChildren(self):
192n/a dom = Document()
193n/a elem = dom.createElement('element')
194n/a text = dom.createTextNode('text')
195n/a self.assertRaises(xml.dom.HierarchyRequestErr, dom.appendChild, text)
196n/a
197n/a dom.appendChild(elem)
198n/a self.assertRaises(xml.dom.HierarchyRequestErr, dom.insertBefore, text,
199n/a elem)
200n/a self.assertRaises(xml.dom.HierarchyRequestErr, dom.replaceChild, text,
201n/a elem)
202n/a
203n/a nodemap = elem.attributes
204n/a self.assertRaises(xml.dom.HierarchyRequestErr, nodemap.setNamedItem,
205n/a text)
206n/a self.assertRaises(xml.dom.HierarchyRequestErr, nodemap.setNamedItemNS,
207n/a text)
208n/a
209n/a elem.appendChild(text)
210n/a dom.unlink()
211n/a
212n/a def testNamedNodeMapSetItem(self):
213n/a dom = Document()
214n/a elem = dom.createElement('element')
215n/a attrs = elem.attributes
216n/a attrs["foo"] = "bar"
217n/a a = attrs.item(0)
218n/a self.confirm(a.ownerDocument is dom,
219n/a "NamedNodeMap.__setitem__() sets ownerDocument")
220n/a self.confirm(a.ownerElement is elem,
221n/a "NamedNodeMap.__setitem__() sets ownerElement")
222n/a self.confirm(a.value == "bar",
223n/a "NamedNodeMap.__setitem__() sets value")
224n/a self.confirm(a.nodeValue == "bar",
225n/a "NamedNodeMap.__setitem__() sets nodeValue")
226n/a elem.unlink()
227n/a dom.unlink()
228n/a
229n/a def testNonZero(self):
230n/a dom = parse(tstfile)
231n/a self.confirm(dom)# should not be zero
232n/a dom.appendChild(dom.createComment("foo"))
233n/a self.confirm(not dom.childNodes[-1].childNodes)
234n/a dom.unlink()
235n/a
236n/a def testUnlink(self):
237n/a dom = parse(tstfile)
238n/a self.assertTrue(dom.childNodes)
239n/a dom.unlink()
240n/a self.assertFalse(dom.childNodes)
241n/a
242n/a def testContext(self):
243n/a with parse(tstfile) as dom:
244n/a self.assertTrue(dom.childNodes)
245n/a self.assertFalse(dom.childNodes)
246n/a
247n/a def testElement(self):
248n/a dom = Document()
249n/a dom.appendChild(dom.createElement("abc"))
250n/a self.confirm(dom.documentElement)
251n/a dom.unlink()
252n/a
253n/a def testAAA(self):
254n/a dom = parseString("<abc/>")
255n/a el = dom.documentElement
256n/a el.setAttribute("spam", "jam2")
257n/a self.confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
258n/a a = el.getAttributeNode("spam")
259n/a self.confirm(a.ownerDocument is dom,
260n/a "setAttribute() sets ownerDocument")
261n/a self.confirm(a.ownerElement is dom.documentElement,
262n/a "setAttribute() sets ownerElement")
263n/a dom.unlink()
264n/a
265n/a def testAAB(self):
266n/a dom = parseString("<abc/>")
267n/a el = dom.documentElement
268n/a el.setAttribute("spam", "jam")
269n/a el.setAttribute("spam", "jam2")
270n/a self.confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
271n/a dom.unlink()
272n/a
273n/a def testAddAttr(self):
274n/a dom = Document()
275n/a child = dom.appendChild(dom.createElement("abc"))
276n/a
277n/a child.setAttribute("def", "ghi")
278n/a self.confirm(child.getAttribute("def") == "ghi")
279n/a self.confirm(child.attributes["def"].value == "ghi")
280n/a
281n/a child.setAttribute("jkl", "mno")
282n/a self.confirm(child.getAttribute("jkl") == "mno")
283n/a self.confirm(child.attributes["jkl"].value == "mno")
284n/a
285n/a self.confirm(len(child.attributes) == 2)
286n/a
287n/a child.setAttribute("def", "newval")
288n/a self.confirm(child.getAttribute("def") == "newval")
289n/a self.confirm(child.attributes["def"].value == "newval")
290n/a
291n/a self.confirm(len(child.attributes) == 2)
292n/a dom.unlink()
293n/a
294n/a def testDeleteAttr(self):
295n/a dom = Document()
296n/a child = dom.appendChild(dom.createElement("abc"))
297n/a
298n/a self.confirm(len(child.attributes) == 0)
299n/a child.setAttribute("def", "ghi")
300n/a self.confirm(len(child.attributes) == 1)
301n/a del child.attributes["def"]
302n/a self.confirm(len(child.attributes) == 0)
303n/a dom.unlink()
304n/a
305n/a def testRemoveAttr(self):
306n/a dom = Document()
307n/a child = dom.appendChild(dom.createElement("abc"))
308n/a
309n/a child.setAttribute("def", "ghi")
310n/a self.confirm(len(child.attributes) == 1)
311n/a self.assertRaises(xml.dom.NotFoundErr, child.removeAttribute, "foo")
312n/a child.removeAttribute("def")
313n/a self.confirm(len(child.attributes) == 0)
314n/a dom.unlink()
315n/a
316n/a def testRemoveAttrNS(self):
317n/a dom = Document()
318n/a child = dom.appendChild(
319n/a dom.createElementNS("http://www.python.org", "python:abc"))
320n/a child.setAttributeNS("http://www.w3.org", "xmlns:python",
321n/a "http://www.python.org")
322n/a child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
323n/a self.assertRaises(xml.dom.NotFoundErr, child.removeAttributeNS,
324n/a "foo", "http://www.python.org")
325n/a self.confirm(len(child.attributes) == 2)
326n/a child.removeAttributeNS("http://www.python.org", "abcattr")
327n/a self.confirm(len(child.attributes) == 1)
328n/a dom.unlink()
329n/a
330n/a def testRemoveAttributeNode(self):
331n/a dom = Document()
332n/a child = dom.appendChild(dom.createElement("foo"))
333n/a child.setAttribute("spam", "jam")
334n/a self.confirm(len(child.attributes) == 1)
335n/a node = child.getAttributeNode("spam")
336n/a self.assertRaises(xml.dom.NotFoundErr, child.removeAttributeNode,
337n/a None)
338n/a child.removeAttributeNode(node)
339n/a self.confirm(len(child.attributes) == 0
340n/a and child.getAttributeNode("spam") is None)
341n/a dom2 = Document()
342n/a child2 = dom2.appendChild(dom2.createElement("foo"))
343n/a node2 = child2.getAttributeNode("spam")
344n/a self.assertRaises(xml.dom.NotFoundErr, child2.removeAttributeNode,
345n/a node2)
346n/a dom.unlink()
347n/a
348n/a def testHasAttribute(self):
349n/a dom = Document()
350n/a child = dom.appendChild(dom.createElement("foo"))
351n/a child.setAttribute("spam", "jam")
352n/a self.confirm(child.hasAttribute("spam"))
353n/a
354n/a def testChangeAttr(self):
355n/a dom = parseString("<abc/>")
356n/a el = dom.documentElement
357n/a el.setAttribute("spam", "jam")
358n/a self.confirm(len(el.attributes) == 1)
359n/a el.setAttribute("spam", "bam")
360n/a # Set this attribute to be an ID and make sure that doesn't change
361n/a # when changing the value:
362n/a el.setIdAttribute("spam")
363n/a self.confirm(len(el.attributes) == 1
364n/a and el.attributes["spam"].value == "bam"
365n/a and el.attributes["spam"].nodeValue == "bam"
366n/a and el.getAttribute("spam") == "bam"
367n/a and el.getAttributeNode("spam").isId)
368n/a el.attributes["spam"] = "ham"
369n/a self.confirm(len(el.attributes) == 1
370n/a and el.attributes["spam"].value == "ham"
371n/a and el.attributes["spam"].nodeValue == "ham"
372n/a and el.getAttribute("spam") == "ham"
373n/a and el.attributes["spam"].isId)
374n/a el.setAttribute("spam2", "bam")
375n/a self.confirm(len(el.attributes) == 2
376n/a and el.attributes["spam"].value == "ham"
377n/a and el.attributes["spam"].nodeValue == "ham"
378n/a and el.getAttribute("spam") == "ham"
379n/a and el.attributes["spam2"].value == "bam"
380n/a and el.attributes["spam2"].nodeValue == "bam"
381n/a and el.getAttribute("spam2") == "bam")
382n/a el.attributes["spam2"] = "bam2"
383n/a self.confirm(len(el.attributes) == 2
384n/a and el.attributes["spam"].value == "ham"
385n/a and el.attributes["spam"].nodeValue == "ham"
386n/a and el.getAttribute("spam") == "ham"
387n/a and el.attributes["spam2"].value == "bam2"
388n/a and el.attributes["spam2"].nodeValue == "bam2"
389n/a and el.getAttribute("spam2") == "bam2")
390n/a dom.unlink()
391n/a
392n/a def testGetAttrList(self):
393n/a pass
394n/a
395n/a def testGetAttrValues(self):
396n/a pass
397n/a
398n/a def testGetAttrLength(self):
399n/a pass
400n/a
401n/a def testGetAttribute(self):
402n/a dom = Document()
403n/a child = dom.appendChild(
404n/a dom.createElementNS("http://www.python.org", "python:abc"))
405n/a self.assertEqual(child.getAttribute('missing'), '')
406n/a
407n/a def testGetAttributeNS(self):
408n/a dom = Document()
409n/a child = dom.appendChild(
410n/a dom.createElementNS("http://www.python.org", "python:abc"))
411n/a child.setAttributeNS("http://www.w3.org", "xmlns:python",
412n/a "http://www.python.org")
413n/a self.assertEqual(child.getAttributeNS("http://www.w3.org", "python"),
414n/a 'http://www.python.org')
415n/a self.assertEqual(child.getAttributeNS("http://www.w3.org", "other"),
416n/a '')
417n/a child2 = child.appendChild(dom.createElement('abc'))
418n/a self.assertEqual(child2.getAttributeNS("http://www.python.org", "missing"),
419n/a '')
420n/a
421n/a def testGetAttributeNode(self): pass
422n/a
423n/a def testGetElementsByTagNameNS(self):
424n/a d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
425n/a <minidom:myelem/>
426n/a </foo>"""
427n/a dom = parseString(d)
428n/a elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom",
429n/a "myelem")
430n/a self.confirm(len(elems) == 1
431n/a and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
432n/a and elems[0].localName == "myelem"
433n/a and elems[0].prefix == "minidom"
434n/a and elems[0].tagName == "minidom:myelem"
435n/a and elems[0].nodeName == "minidom:myelem")
436n/a dom.unlink()
437n/a
438n/a def get_empty_nodelist_from_elements_by_tagName_ns_helper(self, doc, nsuri,
439n/a lname):
440n/a nodelist = doc.getElementsByTagNameNS(nsuri, lname)
441n/a self.confirm(len(nodelist) == 0)
442n/a
443n/a def testGetEmptyNodeListFromElementsByTagNameNS(self):
444n/a doc = parseString('<doc/>')
445n/a self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
446n/a doc, 'http://xml.python.org/namespaces/a', 'localname')
447n/a self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
448n/a doc, '*', 'splat')
449n/a self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
450n/a doc, 'http://xml.python.org/namespaces/a', '*')
451n/a
452n/a doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
453n/a self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
454n/a doc, "http://xml.python.org/splat", "not-there")
455n/a self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
456n/a doc, "*", "not-there")
457n/a self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
458n/a doc, "http://somewhere.else.net/not-there", "e")
459n/a
460n/a def testElementReprAndStr(self):
461n/a dom = Document()
462n/a el = dom.appendChild(dom.createElement("abc"))
463n/a string1 = repr(el)
464n/a string2 = str(el)
465n/a self.confirm(string1 == string2)
466n/a dom.unlink()
467n/a
468n/a def testElementReprAndStrUnicode(self):
469n/a dom = Document()
470n/a el = dom.appendChild(dom.createElement("abc"))
471n/a string1 = repr(el)
472n/a string2 = str(el)
473n/a self.confirm(string1 == string2)
474n/a dom.unlink()
475n/a
476n/a def testElementReprAndStrUnicodeNS(self):
477n/a dom = Document()
478n/a el = dom.appendChild(
479n/a dom.createElementNS("http://www.slashdot.org", "slash:abc"))
480n/a string1 = repr(el)
481n/a string2 = str(el)
482n/a self.confirm(string1 == string2)
483n/a self.confirm("slash:abc" in string1)
484n/a dom.unlink()
485n/a
486n/a def testAttributeRepr(self):
487n/a dom = Document()
488n/a el = dom.appendChild(dom.createElement("abc"))
489n/a node = el.setAttribute("abc", "def")
490n/a self.confirm(str(node) == repr(node))
491n/a dom.unlink()
492n/a
493n/a def testTextNodeRepr(self): pass
494n/a
495n/a def testWriteXML(self):
496n/a str = '<?xml version="1.0" ?><a b="c"/>'
497n/a dom = parseString(str)
498n/a domstr = dom.toxml()
499n/a dom.unlink()
500n/a self.confirm(str == domstr)
501n/a
502n/a def testAltNewline(self):
503n/a str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
504n/a dom = parseString(str)
505n/a domstr = dom.toprettyxml(newl="\r\n")
506n/a dom.unlink()
507n/a self.confirm(domstr == str.replace("\n", "\r\n"))
508n/a
509n/a def test_toprettyxml_with_text_nodes(self):
510n/a # see issue #4147, text nodes are not indented
511n/a decl = '<?xml version="1.0" ?>\n'
512n/a self.assertEqual(parseString('<B>A</B>').toprettyxml(),
513n/a decl + '<B>A</B>\n')
514n/a self.assertEqual(parseString('<C>A<B>A</B></C>').toprettyxml(),
515n/a decl + '<C>\n\tA\n\t<B>A</B>\n</C>\n')
516n/a self.assertEqual(parseString('<C><B>A</B>A</C>').toprettyxml(),
517n/a decl + '<C>\n\t<B>A</B>\n\tA\n</C>\n')
518n/a self.assertEqual(parseString('<C><B>A</B><B>A</B></C>').toprettyxml(),
519n/a decl + '<C>\n\t<B>A</B>\n\t<B>A</B>\n</C>\n')
520n/a self.assertEqual(parseString('<C><B>A</B>A<B>A</B></C>').toprettyxml(),
521n/a decl + '<C>\n\t<B>A</B>\n\tA\n\t<B>A</B>\n</C>\n')
522n/a
523n/a def test_toprettyxml_with_adjacent_text_nodes(self):
524n/a # see issue #4147, adjacent text nodes are indented normally
525n/a dom = Document()
526n/a elem = dom.createElement('elem')
527n/a elem.appendChild(dom.createTextNode('TEXT'))
528n/a elem.appendChild(dom.createTextNode('TEXT'))
529n/a dom.appendChild(elem)
530n/a decl = '<?xml version="1.0" ?>\n'
531n/a self.assertEqual(dom.toprettyxml(),
532n/a decl + '<elem>\n\tTEXT\n\tTEXT\n</elem>\n')
533n/a
534n/a def test_toprettyxml_preserves_content_of_text_node(self):
535n/a # see issue #4147
536n/a for str in ('<B>A</B>', '<A><B>C</B></A>'):
537n/a dom = parseString(str)
538n/a dom2 = parseString(dom.toprettyxml())
539n/a self.assertEqual(
540n/a dom.getElementsByTagName('B')[0].childNodes[0].toxml(),
541n/a dom2.getElementsByTagName('B')[0].childNodes[0].toxml())
542n/a
543n/a def testProcessingInstruction(self):
544n/a dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
545n/a pi = dom.documentElement.firstChild
546n/a self.confirm(pi.target == "mypi"
547n/a and pi.data == "data \t\n "
548n/a and pi.nodeName == "mypi"
549n/a and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
550n/a and pi.attributes is None
551n/a and not pi.hasChildNodes()
552n/a and len(pi.childNodes) == 0
553n/a and pi.firstChild is None
554n/a and pi.lastChild is None
555n/a and pi.localName is None
556n/a and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
557n/a
558n/a def testProcessingInstructionRepr(self): pass
559n/a
560n/a def testTextRepr(self): pass
561n/a
562n/a def testWriteText(self): pass
563n/a
564n/a def testDocumentElement(self): pass
565n/a
566n/a def testTooManyDocumentElements(self):
567n/a doc = parseString("<doc/>")
568n/a elem = doc.createElement("extra")
569n/a # Should raise an exception when adding an extra document element.
570n/a self.assertRaises(xml.dom.HierarchyRequestErr, doc.appendChild, elem)
571n/a elem.unlink()
572n/a doc.unlink()
573n/a
574n/a def testCreateElementNS(self): pass
575n/a
576n/a def testCreateAttributeNS(self): pass
577n/a
578n/a def testParse(self): pass
579n/a
580n/a def testParseString(self): pass
581n/a
582n/a def testComment(self): pass
583n/a
584n/a def testAttrListItem(self): pass
585n/a
586n/a def testAttrListItems(self): pass
587n/a
588n/a def testAttrListItemNS(self): pass
589n/a
590n/a def testAttrListKeys(self): pass
591n/a
592n/a def testAttrListKeysNS(self): pass
593n/a
594n/a def testRemoveNamedItem(self):
595n/a doc = parseString("<doc a=''/>")
596n/a e = doc.documentElement
597n/a attrs = e.attributes
598n/a a1 = e.getAttributeNode("a")
599n/a a2 = attrs.removeNamedItem("a")
600n/a self.confirm(a1.isSameNode(a2))
601n/a self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItem, "a")
602n/a
603n/a def testRemoveNamedItemNS(self):
604n/a doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
605n/a e = doc.documentElement
606n/a attrs = e.attributes
607n/a a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
608n/a a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
609n/a self.confirm(a1.isSameNode(a2))
610n/a self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItemNS,
611n/a "http://xml.python.org/", "b")
612n/a
613n/a def testAttrListValues(self): pass
614n/a
615n/a def testAttrListLength(self): pass
616n/a
617n/a def testAttrList__getitem__(self): pass
618n/a
619n/a def testAttrList__setitem__(self): pass
620n/a
621n/a def testSetAttrValueandNodeValue(self): pass
622n/a
623n/a def testParseElement(self): pass
624n/a
625n/a def testParseAttributes(self): pass
626n/a
627n/a def testParseElementNamespaces(self): pass
628n/a
629n/a def testParseAttributeNamespaces(self): pass
630n/a
631n/a def testParseProcessingInstructions(self): pass
632n/a
633n/a def testChildNodes(self): pass
634n/a
635n/a def testFirstChild(self): pass
636n/a
637n/a def testHasChildNodes(self):
638n/a dom = parseString("<doc><foo/></doc>")
639n/a doc = dom.documentElement
640n/a self.assertTrue(doc.hasChildNodes())
641n/a dom2 = parseString("<doc/>")
642n/a doc2 = dom2.documentElement
643n/a self.assertFalse(doc2.hasChildNodes())
644n/a
645n/a def _testCloneElementCopiesAttributes(self, e1, e2, test):
646n/a attrs1 = e1.attributes
647n/a attrs2 = e2.attributes
648n/a keys1 = list(attrs1.keys())
649n/a keys2 = list(attrs2.keys())
650n/a keys1.sort()
651n/a keys2.sort()
652n/a self.confirm(keys1 == keys2, "clone of element has same attribute keys")
653n/a for i in range(len(keys1)):
654n/a a1 = attrs1.item(i)
655n/a a2 = attrs2.item(i)
656n/a self.confirm(a1 is not a2
657n/a and a1.value == a2.value
658n/a and a1.nodeValue == a2.nodeValue
659n/a and a1.namespaceURI == a2.namespaceURI
660n/a and a1.localName == a2.localName
661n/a , "clone of attribute node has proper attribute values")
662n/a self.confirm(a2.ownerElement is e2,
663n/a "clone of attribute node correctly owned")
664n/a
665n/a def _setupCloneElement(self, deep):
666n/a dom = parseString("<doc attr='value'><foo/></doc>")
667n/a root = dom.documentElement
668n/a clone = root.cloneNode(deep)
669n/a self._testCloneElementCopiesAttributes(
670n/a root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
671n/a # mutilate the original so shared data is detected
672n/a root.tagName = root.nodeName = "MODIFIED"
673n/a root.setAttribute("attr", "NEW VALUE")
674n/a root.setAttribute("added", "VALUE")
675n/a return dom, clone
676n/a
677n/a def testCloneElementShallow(self):
678n/a dom, clone = self._setupCloneElement(0)
679n/a self.confirm(len(clone.childNodes) == 0
680n/a and clone.childNodes.length == 0
681n/a and clone.parentNode is None
682n/a and clone.toxml() == '<doc attr="value"/>'
683n/a , "testCloneElementShallow")
684n/a dom.unlink()
685n/a
686n/a def testCloneElementDeep(self):
687n/a dom, clone = self._setupCloneElement(1)
688n/a self.confirm(len(clone.childNodes) == 1
689n/a and clone.childNodes.length == 1
690n/a and clone.parentNode is None
691n/a and clone.toxml() == '<doc attr="value"><foo/></doc>'
692n/a , "testCloneElementDeep")
693n/a dom.unlink()
694n/a
695n/a def testCloneDocumentShallow(self):
696n/a doc = parseString("<?xml version='1.0'?>\n"
697n/a "<!-- comment -->"
698n/a "<!DOCTYPE doc [\n"
699n/a "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
700n/a "]>\n"
701n/a "<doc attr='value'/>")
702n/a doc2 = doc.cloneNode(0)
703n/a self.confirm(doc2 is None,
704n/a "testCloneDocumentShallow:"
705n/a " shallow cloning of documents makes no sense!")
706n/a
707n/a def testCloneDocumentDeep(self):
708n/a doc = parseString("<?xml version='1.0'?>\n"
709n/a "<!-- comment -->"
710n/a "<!DOCTYPE doc [\n"
711n/a "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
712n/a "]>\n"
713n/a "<doc attr='value'/>")
714n/a doc2 = doc.cloneNode(1)
715n/a self.confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
716n/a "testCloneDocumentDeep: document objects not distinct")
717n/a self.confirm(len(doc.childNodes) == len(doc2.childNodes),
718n/a "testCloneDocumentDeep: wrong number of Document children")
719n/a self.confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
720n/a "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
721n/a self.confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
722n/a "testCloneDocumentDeep: documentElement owner is not new document")
723n/a self.confirm(not doc.documentElement.isSameNode(doc2.documentElement),
724n/a "testCloneDocumentDeep: documentElement should not be shared")
725n/a if doc.doctype is not None:
726n/a # check the doctype iff the original DOM maintained it
727n/a self.confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
728n/a "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
729n/a self.confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
730n/a self.confirm(not doc.doctype.isSameNode(doc2.doctype))
731n/a
732n/a def testCloneDocumentTypeDeepOk(self):
733n/a doctype = create_nonempty_doctype()
734n/a clone = doctype.cloneNode(1)
735n/a self.confirm(clone is not None
736n/a and clone.nodeName == doctype.nodeName
737n/a and clone.name == doctype.name
738n/a and clone.publicId == doctype.publicId
739n/a and clone.systemId == doctype.systemId
740n/a and len(clone.entities) == len(doctype.entities)
741n/a and clone.entities.item(len(clone.entities)) is None
742n/a and len(clone.notations) == len(doctype.notations)
743n/a and clone.notations.item(len(clone.notations)) is None
744n/a and len(clone.childNodes) == 0)
745n/a for i in range(len(doctype.entities)):
746n/a se = doctype.entities.item(i)
747n/a ce = clone.entities.item(i)
748n/a self.confirm((not se.isSameNode(ce))
749n/a and (not ce.isSameNode(se))
750n/a and ce.nodeName == se.nodeName
751n/a and ce.notationName == se.notationName
752n/a and ce.publicId == se.publicId
753n/a and ce.systemId == se.systemId
754n/a and ce.encoding == se.encoding
755n/a and ce.actualEncoding == se.actualEncoding
756n/a and ce.version == se.version)
757n/a for i in range(len(doctype.notations)):
758n/a sn = doctype.notations.item(i)
759n/a cn = clone.notations.item(i)
760n/a self.confirm((not sn.isSameNode(cn))
761n/a and (not cn.isSameNode(sn))
762n/a and cn.nodeName == sn.nodeName
763n/a and cn.publicId == sn.publicId
764n/a and cn.systemId == sn.systemId)
765n/a
766n/a def testCloneDocumentTypeDeepNotOk(self):
767n/a doc = create_doc_with_doctype()
768n/a clone = doc.doctype.cloneNode(1)
769n/a self.confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
770n/a
771n/a def testCloneDocumentTypeShallowOk(self):
772n/a doctype = create_nonempty_doctype()
773n/a clone = doctype.cloneNode(0)
774n/a self.confirm(clone is not None
775n/a and clone.nodeName == doctype.nodeName
776n/a and clone.name == doctype.name
777n/a and clone.publicId == doctype.publicId
778n/a and clone.systemId == doctype.systemId
779n/a and len(clone.entities) == 0
780n/a and clone.entities.item(0) is None
781n/a and len(clone.notations) == 0
782n/a and clone.notations.item(0) is None
783n/a and len(clone.childNodes) == 0)
784n/a
785n/a def testCloneDocumentTypeShallowNotOk(self):
786n/a doc = create_doc_with_doctype()
787n/a clone = doc.doctype.cloneNode(0)
788n/a self.confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
789n/a
790n/a def check_import_document(self, deep, testName):
791n/a doc1 = parseString("<doc/>")
792n/a doc2 = parseString("<doc/>")
793n/a self.assertRaises(xml.dom.NotSupportedErr, doc1.importNode, doc2, deep)
794n/a
795n/a def testImportDocumentShallow(self):
796n/a self.check_import_document(0, "testImportDocumentShallow")
797n/a
798n/a def testImportDocumentDeep(self):
799n/a self.check_import_document(1, "testImportDocumentDeep")
800n/a
801n/a def testImportDocumentTypeShallow(self):
802n/a src = create_doc_with_doctype()
803n/a target = create_doc_without_doctype()
804n/a self.assertRaises(xml.dom.NotSupportedErr, target.importNode,
805n/a src.doctype, 0)
806n/a
807n/a def testImportDocumentTypeDeep(self):
808n/a src = create_doc_with_doctype()
809n/a target = create_doc_without_doctype()
810n/a self.assertRaises(xml.dom.NotSupportedErr, target.importNode,
811n/a src.doctype, 1)
812n/a
813n/a # Testing attribute clones uses a helper, and should always be deep,
814n/a # even if the argument to cloneNode is false.
815n/a def check_clone_attribute(self, deep, testName):
816n/a doc = parseString("<doc attr='value'/>")
817n/a attr = doc.documentElement.getAttributeNode("attr")
818n/a self.assertNotEqual(attr, None)
819n/a clone = attr.cloneNode(deep)
820n/a self.confirm(not clone.isSameNode(attr))
821n/a self.confirm(not attr.isSameNode(clone))
822n/a self.confirm(clone.ownerElement is None,
823n/a testName + ": ownerElement should be None")
824n/a self.confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
825n/a testName + ": ownerDocument does not match")
826n/a self.confirm(clone.specified,
827n/a testName + ": cloned attribute must have specified == True")
828n/a
829n/a def testCloneAttributeShallow(self):
830n/a self.check_clone_attribute(0, "testCloneAttributeShallow")
831n/a
832n/a def testCloneAttributeDeep(self):
833n/a self.check_clone_attribute(1, "testCloneAttributeDeep")
834n/a
835n/a def check_clone_pi(self, deep, testName):
836n/a doc = parseString("<?target data?><doc/>")
837n/a pi = doc.firstChild
838n/a self.assertEqual(pi.nodeType, Node.PROCESSING_INSTRUCTION_NODE)
839n/a clone = pi.cloneNode(deep)
840n/a self.confirm(clone.target == pi.target
841n/a and clone.data == pi.data)
842n/a
843n/a def testClonePIShallow(self):
844n/a self.check_clone_pi(0, "testClonePIShallow")
845n/a
846n/a def testClonePIDeep(self):
847n/a self.check_clone_pi(1, "testClonePIDeep")
848n/a
849n/a def testNormalize(self):
850n/a doc = parseString("<doc/>")
851n/a root = doc.documentElement
852n/a root.appendChild(doc.createTextNode("first"))
853n/a root.appendChild(doc.createTextNode("second"))
854n/a self.confirm(len(root.childNodes) == 2
855n/a and root.childNodes.length == 2,
856n/a "testNormalize -- preparation")
857n/a doc.normalize()
858n/a self.confirm(len(root.childNodes) == 1
859n/a and root.childNodes.length == 1
860n/a and root.firstChild is root.lastChild
861n/a and root.firstChild.data == "firstsecond"
862n/a , "testNormalize -- result")
863n/a doc.unlink()
864n/a
865n/a doc = parseString("<doc/>")
866n/a root = doc.documentElement
867n/a root.appendChild(doc.createTextNode(""))
868n/a doc.normalize()
869n/a self.confirm(len(root.childNodes) == 0
870n/a and root.childNodes.length == 0,
871n/a "testNormalize -- single empty node removed")
872n/a doc.unlink()
873n/a
874n/a def testNormalizeCombineAndNextSibling(self):
875n/a doc = parseString("<doc/>")
876n/a root = doc.documentElement
877n/a root.appendChild(doc.createTextNode("first"))
878n/a root.appendChild(doc.createTextNode("second"))
879n/a root.appendChild(doc.createElement("i"))
880n/a self.confirm(len(root.childNodes) == 3
881n/a and root.childNodes.length == 3,
882n/a "testNormalizeCombineAndNextSibling -- preparation")
883n/a doc.normalize()
884n/a self.confirm(len(root.childNodes) == 2
885n/a and root.childNodes.length == 2
886n/a and root.firstChild.data == "firstsecond"
887n/a and root.firstChild is not root.lastChild
888n/a and root.firstChild.nextSibling is root.lastChild
889n/a and root.firstChild.previousSibling is None
890n/a and root.lastChild.previousSibling is root.firstChild
891n/a and root.lastChild.nextSibling is None
892n/a , "testNormalizeCombinedAndNextSibling -- result")
893n/a doc.unlink()
894n/a
895n/a def testNormalizeDeleteWithPrevSibling(self):
896n/a doc = parseString("<doc/>")
897n/a root = doc.documentElement
898n/a root.appendChild(doc.createTextNode("first"))
899n/a root.appendChild(doc.createTextNode(""))
900n/a self.confirm(len(root.childNodes) == 2
901n/a and root.childNodes.length == 2,
902n/a "testNormalizeDeleteWithPrevSibling -- preparation")
903n/a doc.normalize()
904n/a self.confirm(len(root.childNodes) == 1
905n/a and root.childNodes.length == 1
906n/a and root.firstChild.data == "first"
907n/a and root.firstChild is root.lastChild
908n/a and root.firstChild.nextSibling is None
909n/a and root.firstChild.previousSibling is None
910n/a , "testNormalizeDeleteWithPrevSibling -- result")
911n/a doc.unlink()
912n/a
913n/a def testNormalizeDeleteWithNextSibling(self):
914n/a doc = parseString("<doc/>")
915n/a root = doc.documentElement
916n/a root.appendChild(doc.createTextNode(""))
917n/a root.appendChild(doc.createTextNode("second"))
918n/a self.confirm(len(root.childNodes) == 2
919n/a and root.childNodes.length == 2,
920n/a "testNormalizeDeleteWithNextSibling -- preparation")
921n/a doc.normalize()
922n/a self.confirm(len(root.childNodes) == 1
923n/a and root.childNodes.length == 1
924n/a and root.firstChild.data == "second"
925n/a and root.firstChild is root.lastChild
926n/a and root.firstChild.nextSibling is None
927n/a and root.firstChild.previousSibling is None
928n/a , "testNormalizeDeleteWithNextSibling -- result")
929n/a doc.unlink()
930n/a
931n/a def testNormalizeDeleteWithTwoNonTextSiblings(self):
932n/a doc = parseString("<doc/>")
933n/a root = doc.documentElement
934n/a root.appendChild(doc.createElement("i"))
935n/a root.appendChild(doc.createTextNode(""))
936n/a root.appendChild(doc.createElement("i"))
937n/a self.confirm(len(root.childNodes) == 3
938n/a and root.childNodes.length == 3,
939n/a "testNormalizeDeleteWithTwoSiblings -- preparation")
940n/a doc.normalize()
941n/a self.confirm(len(root.childNodes) == 2
942n/a and root.childNodes.length == 2
943n/a and root.firstChild is not root.lastChild
944n/a and root.firstChild.nextSibling is root.lastChild
945n/a and root.firstChild.previousSibling is None
946n/a and root.lastChild.previousSibling is root.firstChild
947n/a and root.lastChild.nextSibling is None
948n/a , "testNormalizeDeleteWithTwoSiblings -- result")
949n/a doc.unlink()
950n/a
951n/a def testNormalizeDeleteAndCombine(self):
952n/a doc = parseString("<doc/>")
953n/a root = doc.documentElement
954n/a root.appendChild(doc.createTextNode(""))
955n/a root.appendChild(doc.createTextNode("second"))
956n/a root.appendChild(doc.createTextNode(""))
957n/a root.appendChild(doc.createTextNode("fourth"))
958n/a root.appendChild(doc.createTextNode(""))
959n/a self.confirm(len(root.childNodes) == 5
960n/a and root.childNodes.length == 5,
961n/a "testNormalizeDeleteAndCombine -- preparation")
962n/a doc.normalize()
963n/a self.confirm(len(root.childNodes) == 1
964n/a and root.childNodes.length == 1
965n/a and root.firstChild is root.lastChild
966n/a and root.firstChild.data == "secondfourth"
967n/a and root.firstChild.previousSibling is None
968n/a and root.firstChild.nextSibling is None
969n/a , "testNormalizeDeleteAndCombine -- result")
970n/a doc.unlink()
971n/a
972n/a def testNormalizeRecursion(self):
973n/a doc = parseString("<doc>"
974n/a "<o>"
975n/a "<i/>"
976n/a "t"
977n/a #
978n/a #x
979n/a "</o>"
980n/a "<o>"
981n/a "<o>"
982n/a "t2"
983n/a #x2
984n/a "</o>"
985n/a "t3"
986n/a #x3
987n/a "</o>"
988n/a #
989n/a "</doc>")
990n/a root = doc.documentElement
991n/a root.childNodes[0].appendChild(doc.createTextNode(""))
992n/a root.childNodes[0].appendChild(doc.createTextNode("x"))
993n/a root.childNodes[1].childNodes[0].appendChild(doc.createTextNode("x2"))
994n/a root.childNodes[1].appendChild(doc.createTextNode("x3"))
995n/a root.appendChild(doc.createTextNode(""))
996n/a self.confirm(len(root.childNodes) == 3
997n/a and root.childNodes.length == 3
998n/a and len(root.childNodes[0].childNodes) == 4
999n/a and root.childNodes[0].childNodes.length == 4
1000n/a and len(root.childNodes[1].childNodes) == 3
1001n/a and root.childNodes[1].childNodes.length == 3
1002n/a and len(root.childNodes[1].childNodes[0].childNodes) == 2
1003n/a and root.childNodes[1].childNodes[0].childNodes.length == 2
1004n/a , "testNormalize2 -- preparation")
1005n/a doc.normalize()
1006n/a self.confirm(len(root.childNodes) == 2
1007n/a and root.childNodes.length == 2
1008n/a and len(root.childNodes[0].childNodes) == 2
1009n/a and root.childNodes[0].childNodes.length == 2
1010n/a and len(root.childNodes[1].childNodes) == 2
1011n/a and root.childNodes[1].childNodes.length == 2
1012n/a and len(root.childNodes[1].childNodes[0].childNodes) == 1
1013n/a and root.childNodes[1].childNodes[0].childNodes.length == 1
1014n/a , "testNormalize2 -- childNodes lengths")
1015n/a self.confirm(root.childNodes[0].childNodes[1].data == "tx"
1016n/a and root.childNodes[1].childNodes[0].childNodes[0].data == "t2x2"
1017n/a and root.childNodes[1].childNodes[1].data == "t3x3"
1018n/a , "testNormalize2 -- joined text fields")
1019n/a self.confirm(root.childNodes[0].childNodes[1].nextSibling is None
1020n/a and root.childNodes[0].childNodes[1].previousSibling
1021n/a is root.childNodes[0].childNodes[0]
1022n/a and root.childNodes[0].childNodes[0].previousSibling is None
1023n/a and root.childNodes[0].childNodes[0].nextSibling
1024n/a is root.childNodes[0].childNodes[1]
1025n/a and root.childNodes[1].childNodes[1].nextSibling is None
1026n/a and root.childNodes[1].childNodes[1].previousSibling
1027n/a is root.childNodes[1].childNodes[0]
1028n/a and root.childNodes[1].childNodes[0].previousSibling is None
1029n/a and root.childNodes[1].childNodes[0].nextSibling
1030n/a is root.childNodes[1].childNodes[1]
1031n/a , "testNormalize2 -- sibling pointers")
1032n/a doc.unlink()
1033n/a
1034n/a
1035n/a def testBug0777884(self):
1036n/a doc = parseString("<o>text</o>")
1037n/a text = doc.documentElement.childNodes[0]
1038n/a self.assertEqual(text.nodeType, Node.TEXT_NODE)
1039n/a # Should run quietly, doing nothing.
1040n/a text.normalize()
1041n/a doc.unlink()
1042n/a
1043n/a def testBug1433694(self):
1044n/a doc = parseString("<o><i/>t</o>")
1045n/a node = doc.documentElement
1046n/a node.childNodes[1].nodeValue = ""
1047n/a node.normalize()
1048n/a self.confirm(node.childNodes[-1].nextSibling is None,
1049n/a "Final child's .nextSibling should be None")
1050n/a
1051n/a def testSiblings(self):
1052n/a doc = parseString("<doc><?pi?>text?<elm/></doc>")
1053n/a root = doc.documentElement
1054n/a (pi, text, elm) = root.childNodes
1055n/a
1056n/a self.confirm(pi.nextSibling is text and
1057n/a pi.previousSibling is None and
1058n/a text.nextSibling is elm and
1059n/a text.previousSibling is pi and
1060n/a elm.nextSibling is None and
1061n/a elm.previousSibling is text, "testSiblings")
1062n/a
1063n/a doc.unlink()
1064n/a
1065n/a def testParents(self):
1066n/a doc = parseString(
1067n/a "<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
1068n/a root = doc.documentElement
1069n/a elm1 = root.childNodes[0]
1070n/a (elm2a, elm2b) = elm1.childNodes
1071n/a elm3 = elm2b.childNodes[0]
1072n/a
1073n/a self.confirm(root.parentNode is doc and
1074n/a elm1.parentNode is root and
1075n/a elm2a.parentNode is elm1 and
1076n/a elm2b.parentNode is elm1 and
1077n/a elm3.parentNode is elm2b, "testParents")
1078n/a doc.unlink()
1079n/a
1080n/a def testNodeListItem(self):
1081n/a doc = parseString("<doc><e/><e/></doc>")
1082n/a children = doc.childNodes
1083n/a docelem = children[0]
1084n/a self.confirm(children[0] is children.item(0)
1085n/a and children.item(1) is None
1086n/a and docelem.childNodes.item(0) is docelem.childNodes[0]
1087n/a and docelem.childNodes.item(1) is docelem.childNodes[1]
1088n/a and docelem.childNodes.item(0).childNodes.item(0) is None,
1089n/a "test NodeList.item()")
1090n/a doc.unlink()
1091n/a
1092n/a def testEncodings(self):
1093n/a doc = parseString('<foo>&#x20ac;</foo>')
1094n/a self.assertEqual(doc.toxml(),
1095n/a '<?xml version="1.0" ?><foo>\u20ac</foo>')
1096n/a self.assertEqual(doc.toxml('utf-8'),
1097n/a b'<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>')
1098n/a self.assertEqual(doc.toxml('iso-8859-15'),
1099n/a b'<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>')
1100n/a self.assertEqual(doc.toxml('us-ascii'),
1101n/a b'<?xml version="1.0" encoding="us-ascii"?><foo>&#8364;</foo>')
1102n/a self.assertEqual(doc.toxml('utf-16'),
1103n/a '<?xml version="1.0" encoding="utf-16"?>'
1104n/a '<foo>\u20ac</foo>'.encode('utf-16'))
1105n/a
1106n/a # Verify that character decoding errors raise exceptions instead
1107n/a # of crashing
1108n/a self.assertRaises(UnicodeDecodeError, parseString,
1109n/a b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
1110n/a
1111n/a doc.unlink()
1112n/a
1113n/a class UserDataHandler:
1114n/a called = 0
1115n/a def handle(self, operation, key, data, src, dst):
1116n/a dst.setUserData(key, data + 1, self)
1117n/a src.setUserData(key, None, None)
1118n/a self.called = 1
1119n/a
1120n/a def testUserData(self):
1121n/a dom = Document()
1122n/a n = dom.createElement('e')
1123n/a self.confirm(n.getUserData("foo") is None)
1124n/a n.setUserData("foo", None, None)
1125n/a self.confirm(n.getUserData("foo") is None)
1126n/a n.setUserData("foo", 12, 12)
1127n/a n.setUserData("bar", 13, 13)
1128n/a self.confirm(n.getUserData("foo") == 12)
1129n/a self.confirm(n.getUserData("bar") == 13)
1130n/a n.setUserData("foo", None, None)
1131n/a self.confirm(n.getUserData("foo") is None)
1132n/a self.confirm(n.getUserData("bar") == 13)
1133n/a
1134n/a handler = self.UserDataHandler()
1135n/a n.setUserData("bar", 12, handler)
1136n/a c = n.cloneNode(1)
1137n/a self.confirm(handler.called
1138n/a and n.getUserData("bar") is None
1139n/a and c.getUserData("bar") == 13)
1140n/a n.unlink()
1141n/a c.unlink()
1142n/a dom.unlink()
1143n/a
1144n/a def checkRenameNodeSharedConstraints(self, doc, node):
1145n/a # Make sure illegal NS usage is detected:
1146n/a self.assertRaises(xml.dom.NamespaceErr, doc.renameNode, node,
1147n/a "http://xml.python.org/ns", "xmlns:foo")
1148n/a doc2 = parseString("<doc/>")
1149n/a self.assertRaises(xml.dom.WrongDocumentErr, doc2.renameNode, node,
1150n/a xml.dom.EMPTY_NAMESPACE, "foo")
1151n/a
1152n/a def testRenameAttribute(self):
1153n/a doc = parseString("<doc a='v'/>")
1154n/a elem = doc.documentElement
1155n/a attrmap = elem.attributes
1156n/a attr = elem.attributes['a']
1157n/a
1158n/a # Simple renaming
1159n/a attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
1160n/a self.confirm(attr.name == "b"
1161n/a and attr.nodeName == "b"
1162n/a and attr.localName is None
1163n/a and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
1164n/a and attr.prefix is None
1165n/a and attr.value == "v"
1166n/a and elem.getAttributeNode("a") is None
1167n/a and elem.getAttributeNode("b").isSameNode(attr)
1168n/a and attrmap["b"].isSameNode(attr)
1169n/a and attr.ownerDocument.isSameNode(doc)
1170n/a and attr.ownerElement.isSameNode(elem))
1171n/a
1172n/a # Rename to have a namespace, no prefix
1173n/a attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
1174n/a self.confirm(attr.name == "c"
1175n/a and attr.nodeName == "c"
1176n/a and attr.localName == "c"
1177n/a and attr.namespaceURI == "http://xml.python.org/ns"
1178n/a and attr.prefix is None
1179n/a and attr.value == "v"
1180n/a and elem.getAttributeNode("a") is None
1181n/a and elem.getAttributeNode("b") is None
1182n/a and elem.getAttributeNode("c").isSameNode(attr)
1183n/a and elem.getAttributeNodeNS(
1184n/a "http://xml.python.org/ns", "c").isSameNode(attr)
1185n/a and attrmap["c"].isSameNode(attr)
1186n/a and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
1187n/a
1188n/a # Rename to have a namespace, with prefix
1189n/a attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
1190n/a self.confirm(attr.name == "p:d"
1191n/a and attr.nodeName == "p:d"
1192n/a and attr.localName == "d"
1193n/a and attr.namespaceURI == "http://xml.python.org/ns2"
1194n/a and attr.prefix == "p"
1195n/a and attr.value == "v"
1196n/a and elem.getAttributeNode("a") is None
1197n/a and elem.getAttributeNode("b") is None
1198n/a and elem.getAttributeNode("c") is None
1199n/a and elem.getAttributeNodeNS(
1200n/a "http://xml.python.org/ns", "c") is None
1201n/a and elem.getAttributeNode("p:d").isSameNode(attr)
1202n/a and elem.getAttributeNodeNS(
1203n/a "http://xml.python.org/ns2", "d").isSameNode(attr)
1204n/a and attrmap["p:d"].isSameNode(attr)
1205n/a and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
1206n/a
1207n/a # Rename back to a simple non-NS node
1208n/a attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
1209n/a self.confirm(attr.name == "e"
1210n/a and attr.nodeName == "e"
1211n/a and attr.localName is None
1212n/a and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
1213n/a and attr.prefix is None
1214n/a and attr.value == "v"
1215n/a and elem.getAttributeNode("a") is None
1216n/a and elem.getAttributeNode("b") is None
1217n/a and elem.getAttributeNode("c") is None
1218n/a and elem.getAttributeNode("p:d") is None
1219n/a and elem.getAttributeNodeNS(
1220n/a "http://xml.python.org/ns", "c") is None
1221n/a and elem.getAttributeNode("e").isSameNode(attr)
1222n/a and attrmap["e"].isSameNode(attr))
1223n/a
1224n/a self.assertRaises(xml.dom.NamespaceErr, doc.renameNode, attr,
1225n/a "http://xml.python.org/ns", "xmlns")
1226n/a self.checkRenameNodeSharedConstraints(doc, attr)
1227n/a doc.unlink()
1228n/a
1229n/a def testRenameElement(self):
1230n/a doc = parseString("<doc/>")
1231n/a elem = doc.documentElement
1232n/a
1233n/a # Simple renaming
1234n/a elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
1235n/a self.confirm(elem.tagName == "a"
1236n/a and elem.nodeName == "a"
1237n/a and elem.localName is None
1238n/a and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
1239n/a and elem.prefix is None
1240n/a and elem.ownerDocument.isSameNode(doc))
1241n/a
1242n/a # Rename to have a namespace, no prefix
1243n/a elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
1244n/a self.confirm(elem.tagName == "b"
1245n/a and elem.nodeName == "b"
1246n/a and elem.localName == "b"
1247n/a and elem.namespaceURI == "http://xml.python.org/ns"
1248n/a and elem.prefix is None
1249n/a and elem.ownerDocument.isSameNode(doc))
1250n/a
1251n/a # Rename to have a namespace, with prefix
1252n/a elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
1253n/a self.confirm(elem.tagName == "p:c"
1254n/a and elem.nodeName == "p:c"
1255n/a and elem.localName == "c"
1256n/a and elem.namespaceURI == "http://xml.python.org/ns2"
1257n/a and elem.prefix == "p"
1258n/a and elem.ownerDocument.isSameNode(doc))
1259n/a
1260n/a # Rename back to a simple non-NS node
1261n/a elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
1262n/a self.confirm(elem.tagName == "d"
1263n/a and elem.nodeName == "d"
1264n/a and elem.localName is None
1265n/a and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
1266n/a and elem.prefix is None
1267n/a and elem.ownerDocument.isSameNode(doc))
1268n/a
1269n/a self.checkRenameNodeSharedConstraints(doc, elem)
1270n/a doc.unlink()
1271n/a
1272n/a def testRenameOther(self):
1273n/a # We have to create a comment node explicitly since not all DOM
1274n/a # builders used with minidom add comments to the DOM.
1275n/a doc = xml.dom.minidom.getDOMImplementation().createDocument(
1276n/a xml.dom.EMPTY_NAMESPACE, "e", None)
1277n/a node = doc.createComment("comment")
1278n/a self.assertRaises(xml.dom.NotSupportedErr, doc.renameNode, node,
1279n/a xml.dom.EMPTY_NAMESPACE, "foo")
1280n/a doc.unlink()
1281n/a
1282n/a def testWholeText(self):
1283n/a doc = parseString("<doc>a</doc>")
1284n/a elem = doc.documentElement
1285n/a text = elem.childNodes[0]
1286n/a self.assertEqual(text.nodeType, Node.TEXT_NODE)
1287n/a
1288n/a self.checkWholeText(text, "a")
1289n/a elem.appendChild(doc.createTextNode("b"))
1290n/a self.checkWholeText(text, "ab")
1291n/a elem.insertBefore(doc.createCDATASection("c"), text)
1292n/a self.checkWholeText(text, "cab")
1293n/a
1294n/a # make sure we don't cross other nodes
1295n/a splitter = doc.createComment("comment")
1296n/a elem.appendChild(splitter)
1297n/a text2 = doc.createTextNode("d")
1298n/a elem.appendChild(text2)
1299n/a self.checkWholeText(text, "cab")
1300n/a self.checkWholeText(text2, "d")
1301n/a
1302n/a x = doc.createElement("x")
1303n/a elem.replaceChild(x, splitter)
1304n/a splitter = x
1305n/a self.checkWholeText(text, "cab")
1306n/a self.checkWholeText(text2, "d")
1307n/a
1308n/a x = doc.createProcessingInstruction("y", "z")
1309n/a elem.replaceChild(x, splitter)
1310n/a splitter = x
1311n/a self.checkWholeText(text, "cab")
1312n/a self.checkWholeText(text2, "d")
1313n/a
1314n/a elem.removeChild(splitter)
1315n/a self.checkWholeText(text, "cabd")
1316n/a self.checkWholeText(text2, "cabd")
1317n/a
1318n/a def testPatch1094164(self):
1319n/a doc = parseString("<doc><e/></doc>")
1320n/a elem = doc.documentElement
1321n/a e = elem.firstChild
1322n/a self.confirm(e.parentNode is elem, "Before replaceChild()")
1323n/a # Check that replacing a child with itself leaves the tree unchanged
1324n/a elem.replaceChild(e, e)
1325n/a self.confirm(e.parentNode is elem, "After replaceChild()")
1326n/a
1327n/a def testReplaceWholeText(self):
1328n/a def setup():
1329n/a doc = parseString("<doc>a<e/>d</doc>")
1330n/a elem = doc.documentElement
1331n/a text1 = elem.firstChild
1332n/a text2 = elem.lastChild
1333n/a splitter = text1.nextSibling
1334n/a elem.insertBefore(doc.createTextNode("b"), splitter)
1335n/a elem.insertBefore(doc.createCDATASection("c"), text1)
1336n/a return doc, elem, text1, splitter, text2
1337n/a
1338n/a doc, elem, text1, splitter, text2 = setup()
1339n/a text = text1.replaceWholeText("new content")
1340n/a self.checkWholeText(text, "new content")
1341n/a self.checkWholeText(text2, "d")
1342n/a self.confirm(len(elem.childNodes) == 3)
1343n/a
1344n/a doc, elem, text1, splitter, text2 = setup()
1345n/a text = text2.replaceWholeText("new content")
1346n/a self.checkWholeText(text, "new content")
1347n/a self.checkWholeText(text1, "cab")
1348n/a self.confirm(len(elem.childNodes) == 5)
1349n/a
1350n/a doc, elem, text1, splitter, text2 = setup()
1351n/a text = text1.replaceWholeText("")
1352n/a self.checkWholeText(text2, "d")
1353n/a self.confirm(text is None
1354n/a and len(elem.childNodes) == 2)
1355n/a
1356n/a def testSchemaType(self):
1357n/a doc = parseString(
1358n/a "<!DOCTYPE doc [\n"
1359n/a " <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
1360n/a " <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
1361n/a " <!ATTLIST doc id ID #IMPLIED \n"
1362n/a " ref IDREF #IMPLIED \n"
1363n/a " refs IDREFS #IMPLIED \n"
1364n/a " enum (a|b) #IMPLIED \n"
1365n/a " ent ENTITY #IMPLIED \n"
1366n/a " ents ENTITIES #IMPLIED \n"
1367n/a " nm NMTOKEN #IMPLIED \n"
1368n/a " nms NMTOKENS #IMPLIED \n"
1369n/a " text CDATA #IMPLIED \n"
1370n/a " >\n"
1371n/a "]><doc id='name' notid='name' text='splat!' enum='b'"
1372n/a " ref='name' refs='name name' ent='e1' ents='e1 e2'"
1373n/a " nm='123' nms='123 abc' />")
1374n/a elem = doc.documentElement
1375n/a # We don't want to rely on any specific loader at this point, so
1376n/a # just make sure we can get to all the names, and that the
1377n/a # DTD-based namespace is right. The names can vary by loader
1378n/a # since each supports a different level of DTD information.
1379n/a t = elem.schemaType
1380n/a self.confirm(t.name is None
1381n/a and t.namespace == xml.dom.EMPTY_NAMESPACE)
1382n/a names = "id notid text enum ref refs ent ents nm nms".split()
1383n/a for name in names:
1384n/a a = elem.getAttributeNode(name)
1385n/a t = a.schemaType
1386n/a self.confirm(hasattr(t, "name")
1387n/a and t.namespace == xml.dom.EMPTY_NAMESPACE)
1388n/a
1389n/a def testSetIdAttribute(self):
1390n/a doc = parseString("<doc a1='v' a2='w'/>")
1391n/a e = doc.documentElement
1392n/a a1 = e.getAttributeNode("a1")
1393n/a a2 = e.getAttributeNode("a2")
1394n/a self.confirm(doc.getElementById("v") is None
1395n/a and not a1.isId
1396n/a and not a2.isId)
1397n/a e.setIdAttribute("a1")
1398n/a self.confirm(e.isSameNode(doc.getElementById("v"))
1399n/a and a1.isId
1400n/a and not a2.isId)
1401n/a e.setIdAttribute("a2")
1402n/a self.confirm(e.isSameNode(doc.getElementById("v"))
1403n/a and e.isSameNode(doc.getElementById("w"))
1404n/a and a1.isId
1405n/a and a2.isId)
1406n/a # replace the a1 node; the new node should *not* be an ID
1407n/a a3 = doc.createAttribute("a1")
1408n/a a3.value = "v"
1409n/a e.setAttributeNode(a3)
1410n/a self.confirm(doc.getElementById("v") is None
1411n/a and e.isSameNode(doc.getElementById("w"))
1412n/a and not a1.isId
1413n/a and a2.isId
1414n/a and not a3.isId)
1415n/a # renaming an attribute should not affect its ID-ness:
1416n/a doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1417n/a self.confirm(e.isSameNode(doc.getElementById("w"))
1418n/a and a2.isId)
1419n/a
1420n/a def testSetIdAttributeNS(self):
1421n/a NS1 = "http://xml.python.org/ns1"
1422n/a NS2 = "http://xml.python.org/ns2"
1423n/a doc = parseString("<doc"
1424n/a " xmlns:ns1='" + NS1 + "'"
1425n/a " xmlns:ns2='" + NS2 + "'"
1426n/a " ns1:a1='v' ns2:a2='w'/>")
1427n/a e = doc.documentElement
1428n/a a1 = e.getAttributeNodeNS(NS1, "a1")
1429n/a a2 = e.getAttributeNodeNS(NS2, "a2")
1430n/a self.confirm(doc.getElementById("v") is None
1431n/a and not a1.isId
1432n/a and not a2.isId)
1433n/a e.setIdAttributeNS(NS1, "a1")
1434n/a self.confirm(e.isSameNode(doc.getElementById("v"))
1435n/a and a1.isId
1436n/a and not a2.isId)
1437n/a e.setIdAttributeNS(NS2, "a2")
1438n/a self.confirm(e.isSameNode(doc.getElementById("v"))
1439n/a and e.isSameNode(doc.getElementById("w"))
1440n/a and a1.isId
1441n/a and a2.isId)
1442n/a # replace the a1 node; the new node should *not* be an ID
1443n/a a3 = doc.createAttributeNS(NS1, "a1")
1444n/a a3.value = "v"
1445n/a e.setAttributeNode(a3)
1446n/a self.confirm(e.isSameNode(doc.getElementById("w")))
1447n/a self.confirm(not a1.isId)
1448n/a self.confirm(a2.isId)
1449n/a self.confirm(not a3.isId)
1450n/a self.confirm(doc.getElementById("v") is None)
1451n/a # renaming an attribute should not affect its ID-ness:
1452n/a doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1453n/a self.confirm(e.isSameNode(doc.getElementById("w"))
1454n/a and a2.isId)
1455n/a
1456n/a def testSetIdAttributeNode(self):
1457n/a NS1 = "http://xml.python.org/ns1"
1458n/a NS2 = "http://xml.python.org/ns2"
1459n/a doc = parseString("<doc"
1460n/a " xmlns:ns1='" + NS1 + "'"
1461n/a " xmlns:ns2='" + NS2 + "'"
1462n/a " ns1:a1='v' ns2:a2='w'/>")
1463n/a e = doc.documentElement
1464n/a a1 = e.getAttributeNodeNS(NS1, "a1")
1465n/a a2 = e.getAttributeNodeNS(NS2, "a2")
1466n/a self.confirm(doc.getElementById("v") is None
1467n/a and not a1.isId
1468n/a and not a2.isId)
1469n/a e.setIdAttributeNode(a1)
1470n/a self.confirm(e.isSameNode(doc.getElementById("v"))
1471n/a and a1.isId
1472n/a and not a2.isId)
1473n/a e.setIdAttributeNode(a2)
1474n/a self.confirm(e.isSameNode(doc.getElementById("v"))
1475n/a and e.isSameNode(doc.getElementById("w"))
1476n/a and a1.isId
1477n/a and a2.isId)
1478n/a # replace the a1 node; the new node should *not* be an ID
1479n/a a3 = doc.createAttributeNS(NS1, "a1")
1480n/a a3.value = "v"
1481n/a e.setAttributeNode(a3)
1482n/a self.confirm(e.isSameNode(doc.getElementById("w")))
1483n/a self.confirm(not a1.isId)
1484n/a self.confirm(a2.isId)
1485n/a self.confirm(not a3.isId)
1486n/a self.confirm(doc.getElementById("v") is None)
1487n/a # renaming an attribute should not affect its ID-ness:
1488n/a doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1489n/a self.confirm(e.isSameNode(doc.getElementById("w"))
1490n/a and a2.isId)
1491n/a
1492n/a def assert_recursive_equal(self, doc, doc2):
1493n/a stack = [(doc, doc2)]
1494n/a while stack:
1495n/a n1, n2 = stack.pop()
1496n/a self.assertEqual(n1.nodeType, n2.nodeType)
1497n/a self.assertEqual(len(n1.childNodes), len(n2.childNodes))
1498n/a self.assertEqual(n1.nodeName, n2.nodeName)
1499n/a self.assertFalse(n1.isSameNode(n2))
1500n/a self.assertFalse(n2.isSameNode(n1))
1501n/a if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
1502n/a len(n1.entities)
1503n/a len(n2.entities)
1504n/a len(n1.notations)
1505n/a len(n2.notations)
1506n/a self.assertEqual(len(n1.entities), len(n2.entities))
1507n/a self.assertEqual(len(n1.notations), len(n2.notations))
1508n/a for i in range(len(n1.notations)):
1509n/a # XXX this loop body doesn't seem to be executed?
1510n/a no1 = n1.notations.item(i)
1511n/a no2 = n1.notations.item(i)
1512n/a self.assertEqual(no1.name, no2.name)
1513n/a self.assertEqual(no1.publicId, no2.publicId)
1514n/a self.assertEqual(no1.systemId, no2.systemId)
1515n/a stack.append((no1, no2))
1516n/a for i in range(len(n1.entities)):
1517n/a e1 = n1.entities.item(i)
1518n/a e2 = n2.entities.item(i)
1519n/a self.assertEqual(e1.notationName, e2.notationName)
1520n/a self.assertEqual(e1.publicId, e2.publicId)
1521n/a self.assertEqual(e1.systemId, e2.systemId)
1522n/a stack.append((e1, e2))
1523n/a if n1.nodeType != Node.DOCUMENT_NODE:
1524n/a self.assertTrue(n1.ownerDocument.isSameNode(doc))
1525n/a self.assertTrue(n2.ownerDocument.isSameNode(doc2))
1526n/a for i in range(len(n1.childNodes)):
1527n/a stack.append((n1.childNodes[i], n2.childNodes[i]))
1528n/a
1529n/a def testPickledDocument(self):
1530n/a doc = parseString(sample)
1531n/a for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1532n/a s = pickle.dumps(doc, proto)
1533n/a doc2 = pickle.loads(s)
1534n/a self.assert_recursive_equal(doc, doc2)
1535n/a
1536n/a def testDeepcopiedDocument(self):
1537n/a doc = parseString(sample)
1538n/a doc2 = copy.deepcopy(doc)
1539n/a self.assert_recursive_equal(doc, doc2)
1540n/a
1541n/a def testSerializeCommentNodeWithDoubleHyphen(self):
1542n/a doc = create_doc_without_doctype()
1543n/a doc.appendChild(doc.createComment("foo--bar"))
1544n/a self.assertRaises(ValueError, doc.toxml)
1545n/a
1546n/a
1547n/a def testEmptyXMLNSValue(self):
1548n/a doc = parseString("<element xmlns=''>\n"
1549n/a "<foo/>\n</element>")
1550n/a doc2 = parseString(doc.toxml())
1551n/a self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE)
1552n/a
1553n/a def testExceptionOnSpacesInXMLNSValue(self):
1554n/a with self.assertRaisesRegex(ValueError, 'Unsupported syntax'):
1555n/a parseString('<element xmlns:abc="http:abc.com/de f g/hi/j k"><abc:foo /></element>')
1556n/a
1557n/a def testDocRemoveChild(self):
1558n/a doc = parse(tstfile)
1559n/a title_tag = doc.documentElement.getElementsByTagName("TITLE")[0]
1560n/a self.assertRaises( xml.dom.NotFoundErr, doc.removeChild, title_tag)
1561n/a num_children_before = len(doc.childNodes)
1562n/a doc.removeChild(doc.childNodes[0])
1563n/a num_children_after = len(doc.childNodes)
1564n/a self.assertTrue(num_children_after == num_children_before - 1)
1565n/a
1566n/a def testProcessingInstructionNameError(self):
1567n/a # wrong variable in .nodeValue property will
1568n/a # lead to "NameError: name 'data' is not defined"
1569n/a doc = parse(tstfile)
1570n/a pi = doc.createProcessingInstruction("y", "z")
1571n/a pi.nodeValue = "crash"
1572n/a
1573n/aif __name__ == "__main__":
1574n/a unittest.main()