66from test import support
77import unittest
88
9+ import xml .dom .expatbuilder
910import xml .dom .minidom
1011
1112from xml .dom .minidom import parse , Attr , Node , Document , Element , parseString
@@ -1277,6 +1278,65 @@ def testCloneElementDeep(self):
12771278 self .assertTrue (clone .toxml (), '<doc attr="value"><foo/></doc>' )
12781279 dom .unlink ()
12791280
1281+ def create_dom1_element (self ):
1282+ # DOM Level 1 nodes have no namespace, but their names can contain
1283+ # a colon.
1284+ doc = Document ()
1285+ root = doc .appendChild (doc .createElement ("root" ))
1286+ root .setAttribute ("xmlns" , "http://xml.python.org/default" )
1287+ root .setAttribute ("xmlns:xsi" , "http://xml.python.org/xsi" )
1288+ root .setAttribute ("xsi:type" , "t" )
1289+ root .appendChild (doc .createElement ("svg:rect" ))
1290+ return doc , root
1291+
1292+ def check_dom1_names (self , node , nodeName , prefix , localName ):
1293+ self .assertEqual (node .nodeName , nodeName )
1294+ self .assertEqual (node .prefix , prefix )
1295+ self .assertEqual (node .localName , localName )
1296+ self .assertIsNone (node .namespaceURI )
1297+
1298+ def check_dom1_element (self , elem , doc ):
1299+ self .assertIs (elem .ownerDocument , doc )
1300+ self .check_dom1_names (elem , "root" , None , "root" )
1301+ self .assertEqual (len (elem .attributes ), 3 )
1302+ for name , prefix , localName , value in [
1303+ ("xmlns" , None , "xmlns" , "http://xml.python.org/default" ),
1304+ ("xmlns:xsi" , "xmlns" , "xsi" , "http://xml.python.org/xsi" ),
1305+ ("xsi:type" , "xsi" , "type" , "t" ),
1306+ ]:
1307+ with self .subTest (name = name ):
1308+ attr = elem .getAttributeNode (name )
1309+ self .check_dom1_names (attr , name , prefix , localName )
1310+ self .assertEqual (attr .value , value )
1311+ self .assertIs (attr .ownerElement , elem )
1312+ self .assertIs (attr .ownerDocument , doc )
1313+ self .assertEqual (len (elem .childNodes ), 1 )
1314+ self .check_dom1_names (elem .firstChild , "svg:rect" , "svg" , "rect" )
1315+ self .assertIs (elem .firstChild .ownerDocument , doc )
1316+
1317+ def testCloneElementDOM1Names (self ):
1318+ doc , root = self .create_dom1_element ()
1319+ clone = root .cloneNode (True )
1320+ self .assertIsNot (clone , root )
1321+ self .assertIsNone (clone .parentNode )
1322+ self .check_dom1_element (clone , doc )
1323+ doc .unlink ()
1324+
1325+ def testCloneElementNoNamespaces (self ):
1326+ doc = xml .dom .expatbuilder .parseString (
1327+ "<a:b xmlns:a='http://xml.python.org/a' a:x='1'><a:c/></a:b>" ,
1328+ namespaces = False )
1329+ clone = doc .documentElement .cloneNode (True )
1330+ self .check_dom1_names (clone , "a:b" , "a" , "b" )
1331+ self .assertEqual (clone .getAttribute ("xmlns:a" ),
1332+ "http://xml.python.org/a" )
1333+ self .check_dom1_names (clone .getAttributeNode ("xmlns:a" ),
1334+ "xmlns:a" , "xmlns" , "a" )
1335+ self .assertEqual (clone .getAttribute ("a:x" ), "1" )
1336+ self .check_dom1_names (clone .getAttributeNode ("a:x" ), "a:x" , "a" , "x" )
1337+ self .check_dom1_names (clone .firstChild , "a:c" , "a" , "c" )
1338+ doc .unlink ()
1339+
12801340 def testCloneDocumentShallow (self ):
12811341 doc = parseString ("<?xml version='1.0'?>\n "
12821342 "<!-- comment -->"
@@ -1395,6 +1455,15 @@ def testImportDocumentTypeDeep(self):
13951455 self .assertRaises (xml .dom .NotSupportedErr , target .importNode ,
13961456 src .doctype , 1 )
13971457
1458+ def testImportElementDOM1Names (self ):
1459+ doc1 , root = self .create_dom1_element ()
1460+ doc2 = Document ()
1461+ imported = doc2 .importNode (root , True )
1462+ self .assertIsNone (imported .parentNode )
1463+ self .check_dom1_element (imported , doc2 )
1464+ doc1 .unlink ()
1465+ doc2 .unlink ()
1466+
13981467 # Testing attribute clones uses a helper, and should always be deep,
13991468 # even if the argument to cloneNode is false.
14001469 def check_clone_attribute (self , deep , testName ):
@@ -1417,6 +1486,24 @@ def testCloneAttributeShallow(self):
14171486 def testCloneAttributeDeep (self ):
14181487 self .check_clone_attribute (1 , "testCloneAttributeDeep" )
14191488
1489+ def testCloneAttributeDOM1Names (self ):
1490+ doc1 = Document ()
1491+ attr = doc1 .createAttribute ("a:b" )
1492+ attr .value = "v"
1493+ doc2 = Document ()
1494+ for method , clone , owner in [
1495+ ("cloneNode" , attr .cloneNode (True ), doc1 ),
1496+ ("importNode" , doc2 .importNode (attr , True ), doc2 ),
1497+ ]:
1498+ with self .subTest (method = method ):
1499+ self .check_dom1_names (clone , "a:b" , "a" , "b" )
1500+ self .assertEqual (clone .value , "v" )
1501+ self .assertTrue (clone .specified )
1502+ self .assertIsNone (clone .ownerElement )
1503+ self .assertIs (clone .ownerDocument , owner )
1504+ doc1 .unlink ()
1505+ doc2 .unlink ()
1506+
14201507 def check_clone_pi (self , deep , testName ):
14211508 doc = parseString ("<?target data?><doc/>" )
14221509 pi = doc .firstChild
0 commit comments