Repository: ncclient/ncclient

Issue:
Let sub_ele inherit parent namespace per default
sub_ele defaults to using the `urn:ietf:params:xml:ns:netconf:base:1.0` namespace.

Further, unlike new_ele for which there is a new_ele_ns that also accepts a namespace, there is no such equivalent for sub_ele. How am I supposed to add subelement in my namespace of choice?

I suggest that:
 * a sub_ele_ns is introduced which let's the user specify the namespace to use
 * that sub_ele defaults to using the namespace of its parent

I implemented the first https://github.com/plajjan/ncclient/commit/8ab482b19c5135987f947de812eabc6077740dc2 (can open PR..). The second addition would greatly reduce the code required since it's very very common that nodes actually use the same namespace as their parent. I'm happy to put that in as a PR too.

Apologies if I've just misunderstood how this is supposed to work.

Discussion:

Patch:
diff --git a/ncclient/xml_.py b/ncclient/xml_.py
index 84dbff0..8e81c81 100644
--- a/ncclient/xml_.py
+++ b/ncclient/xml_.py
@@ -223,11 +223,15 @@ class NCElement(object):
                                        parser=self.__parser)
         return self.__root
 
+def parent_ns(node):
+    if node.prefix:
+        return node.nsmap[node.prefix]
+    return None
 
 new_ele = lambda tag, attrs={}, **extra: etree.Element(qualify(tag), attrs, **extra)
 
 new_ele_ns = lambda tag, ns, attrs={}, **extra: etree.Element(qualify(tag,ns), attrs, **extra)
 
-sub_ele = lambda parent, tag, attrs={}, **extra: etree.SubElement(parent, qualify(tag), attrs, **extra)
+sub_ele = lambda parent, tag, attrs={}, **extra: etree.SubElement(parent, qualify(tag, parent_ns(parent)), attrs, **extra)
 
 sub_ele_ns = lambda parent, tag, ns, attrs={}, **extra: etree.SubElement(parent, qualify(tag, ns), attrs, **extra)


Test patch:
diff --git a/test/unit/test_xml_.py b/test/unit/test_xml_.py
index cbdc125..742e851 100644
--- a/test/unit/test_xml_.py
+++ b/test/unit/test_xml_.py
@@ -176,3 +176,16 @@ class TestXML(unittest.TestCase):
         result_xml = result.data_xml
         self.assertRaises(XMLError,
             validated_element, result_xml, tags=["rpc"])
+
+    def test_sub_ele_inherit_parent_namespace(self):
+        device_params = {'name': 'junos'}
+        device_handler = manager.make_device_handler(device_params)
+        transform_reply = device_handler.transform_reply()
+        result = NCElement(self.reply, transform_reply)
+        ele = new_ele_ns(result.find("./cli").tag, "http://www.xxx.org")
+        child = sub_ele(ele, "child")
+        sibling = sub_ele(ele, "sibling")
+        grandchild = sub_ele(child, "grandchild")
+        self.assertEqual(child.tag, "{http://www.xxx.org}child")
+        self.assertEqual(sibling.tag, "{http://www.xxx.org}sibling")
+        self.assertEqual(grandchild.tag, "{http://www.xxx.org}grandchild")