1.1 --- a/libxml2dom/macrolib/macrolib.py Mon Dec 12 00:47:04 2005 +0000
1.2 +++ b/libxml2dom/macrolib/macrolib.py Mon Dec 12 00:48:47 2005 +0000
1.3 @@ -45,6 +45,35 @@
1.4 # NOTE: Should raise an exception.
1.5 return None, None
1.6
1.7 +def _find_namespace(node, ns, prefix):
1.8 + new_ns = None
1.9 + current = libxml2mod.xmlNodeGetNsDefs(node)
1.10 + while current is not None:
1.11 + if _check_namespace(current, ns, prefix):
1.12 + new_ns = current
1.13 + break
1.14 + current = libxml2mod.next(current)
1.15 + if new_ns is None:
1.16 + node_ns = libxml2mod.xmlNodeGetNs(node)
1.17 + if node_ns is not None and _check_namespace(node_ns, ns, prefix):
1.18 + new_ns = node_ns
1.19 + return new_ns
1.20 +
1.21 +def _check_namespace(current, ns, prefix):
1.22 + current_ns = libxml2mod.xmlNodeGetContent(current)
1.23 + current_prefix = libxml2mod.name(current)
1.24 + if ns == current_ns and prefix == current_prefix:
1.25 + return 1
1.26 + else:
1.27 + return 0
1.28 +
1.29 +def _make_namespace(node, ns, prefix, set_default=0):
1.30 + if prefix is not None or set_default:
1.31 + new_ns = libxml2mod.xmlNewNs(node, ns, prefix)
1.32 + else:
1.33 + new_ns = None
1.34 + return new_ns
1.35 +
1.36 _nodeTypes = {
1.37 "attribute" : xml.dom.Node.ATTRIBUTE_NODE,
1.38 "comment" : xml.dom.Node.COMMENT_NODE,
1.39 @@ -180,25 +209,22 @@
1.40 return Node_attributes(node)[(None, name)]
1.41
1.42 def Node_setAttributeNS(node, ns, name, value):
1.43 - # NOTE: Need to convert from Unicode.
1.44 ns, name, value = map(from_unicode, [ns, name, value])
1.45 -
1.46 prefix, localName = _get_prefix_and_localName(name)
1.47 -
1.48 - # NOTE: Might need to be xmlSetNsProp.
1.49 - if ns is not None and ns == libxml2mod.xmlNodeGetContent(libxml2mod.xmlNodeGetNs(node)):
1.50 - libxml2mod.xmlNewNsProp(node, libxml2mod.xmlNodeGetNs(node), localName, value)
1.51 - elif prefix is not None:
1.52 - new_ns = libxml2mod.xmlNewNs(node, ns, prefix)
1.53 - libxml2mod.xmlNewNsProp(node, new_ns, localName, value)
1.54 + if ns is not None:
1.55 + if prefix == "xmlns" and ns == xml.dom.XMLNS_NAMESPACE and _find_namespace(node, value, localName):
1.56 + return
1.57 + new_ns = _find_namespace(node, ns, prefix)
1.58 + if new_ns is None:
1.59 + new_ns = _make_namespace(node, ns, prefix, set_default=0)
1.60 + libxml2mod.xmlSetNsProp(node, new_ns, localName, value)
1.61 else:
1.62 # NOTE: Needs verifying: what should happen to the namespace?
1.63 # NOTE: This also catches the case where None is the element's
1.64 # NOTE: namespace and is also used for the attribute.
1.65 - libxml2mod.xmlNewNsProp(node, None, localName, value)
1.66 + libxml2mod.xmlSetNsProp(node, None, localName, value)
1.67
1.68 def Node_setAttribute(node, name, value):
1.69 - # NOTE: Need to convert from Unicode.
1.70 name, value = map(from_unicode, [name, value])
1.71
1.72 libxml2mod.xmlSetProp(node, name, value)
1.73 @@ -220,7 +246,6 @@
1.74 libxml2mod.xmlUnsetProp(node, name)
1.75
1.76 def Node_createElementNS(node, ns, name):
1.77 - # NOTE: Need to convert from Unicode.
1.78 ns, name = map(from_unicode, [ns, name])
1.79
1.80 prefix, localName = _get_prefix_and_localName(name)
1.81 @@ -228,11 +253,15 @@
1.82
1.83 # If the namespace is not empty, set the declaration.
1.84 if ns is not None:
1.85 - new_ns = libxml2mod.xmlNewNs(new_node, ns, prefix)
1.86 + new_ns = _find_namespace(new_node, ns, prefix)
1.87 + if new_ns is None:
1.88 + new_ns = _make_namespace(new_node, ns, prefix, set_default=1)
1.89 libxml2mod.xmlSetNs(new_node, new_ns)
1.90 # If the namespace is empty, set a "null" declaration.
1.91 elif prefix is not None:
1.92 - new_ns = libxml2mod.xmlNewNs(new_node, "", prefix)
1.93 + new_ns = _find_namespace(new_node, "", prefix)
1.94 + if new_ns is None:
1.95 + new_ns = _make_namespace(new_node, "", prefix)
1.96 libxml2mod.xmlSetNs(new_node, new_ns)
1.97 else:
1.98 libxml2mod.xmlSetNs(new_node, None)
1.99 @@ -240,42 +269,37 @@
1.100 return new_node
1.101
1.102 def Node_createElement(node, name):
1.103 - # NOTE: Need to convert from Unicode.
1.104 name = from_unicode(name)
1.105
1.106 new_node = libxml2mod.xmlNewNode(name)
1.107 return new_node
1.108
1.109 def Node_createAttributeNS(node, ns, name):
1.110 -
1.111 - # NOTE: Need to convert from Unicode.
1.112 ns, name = map(from_unicode, [ns, name])
1.113
1.114 prefix, localName = _get_prefix_and_localName(name)
1.115 # NOTE: Does it make sense to set the namespace if it is empty?
1.116 if ns is not None:
1.117 - new_ns = libxml2mod.xmlNewNs(node, ns, prefix)
1.118 + new_ns = _find_namespace(node, ns, prefix)
1.119 + if new_ns is None:
1.120 + new_ns = _make_namespace(node, ns, prefix, set_default=0)
1.121 else:
1.122 new_ns = None
1.123 new_node = libxml2mod.xmlNewNsProp(node, new_ns, localName, None)
1.124 return new_node
1.125
1.126 def Node_createAttribute(node, name):
1.127 -
1.128 - # NOTE: Need to convert from Unicode.
1.129 name = from_unicode(name)
1.130
1.131 # NOTE: xmlNewProp does not seem to work.
1.132 return Node_createAttributeNS(node, None, name)
1.133
1.134 def Node_createTextNode(node, value):
1.135 - # NOTE: Need to convert from Unicode.
1.136 value = from_unicode(value)
1.137
1.138 return libxml2mod.xmlNewText(value)
1.139
1.140 def Node_createComment(node, value):
1.141 - # NOTE: Need to convert from Unicode.
1.142 value = from_unicode(value)
1.143
1.144 return libxml2mod.xmlNewComment(value)
1.145 @@ -337,7 +361,6 @@
1.146 raise ValueError, "Node type '%s' (%d) not supported." % (_reverseNodeTypes[other.nodeType], other.nodeType)
1.147
1.148 def Node_xpath(node, expr, variables=None, namespaces=None):
1.149 - # NOTE: Need to convert from Unicode.
1.150 expr = from_unicode(expr)
1.151
1.152 context = libxml2mod.xmlXPathNewContext(Node_ownerDocument(node))
1.153 @@ -349,7 +372,6 @@
1.154 libxml2mod.xmlXPathRegisterNs(context, prefix, ns)
1.155 # NOTE: No such functions are exposed in current versions of libxml2.
1.156 #for (prefix, ns), value in (variables or {}).items():
1.157 - # # NOTE: Need to convert from Unicode.
1.158 # value = from_unicode(value)
1.159 # libxml2mod.xmlXPathRegisterVariableNS(context, prefix, ns, value)
1.160 result = libxml2mod.xmlXPathEval(expr, context)