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)

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.
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")

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov sphinx flake8 mock nose
apt-get update apt-get install -y gcc libxml2-dev libxslt1-dev
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs==22.2.0
Babel==2.11.0
bcrypt==4.0.1
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
coverage==6.2
cryptography==40.0.2
docutils==0.18.1
flake8==3.9.2
idna==3.10
imagesize==1.4.1
importlib-metadata==4.8.3
iniconfig==1.1.1
Jinja2==3.0.3
lxml==5.3.1
MarkupSafe==2.0.1
mccabe==0.6.1
mock==5.2.0
-e git+https://github.com/ncclient/ncclient.git@1f8697150508175aa6a7452e4f035ed7de38ae5f#egg=ncclient
nose==1.3.7
packaging==21.3
paramiko==3.5.1
pluggy==1.0.0
py==1.11.0
pycodestyle==2.7.0
pycparser==2.21
pyflakes==2.3.1
Pygments==2.14.0
PyNaCl==1.5.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
pytz==2025.2
requests==2.27.1
six==1.17.0
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: ncclient
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==22.2.0
      - babel==2.11.0
      - bcrypt==4.0.1
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - coverage==6.2
      - cryptography==40.0.2
      - docutils==0.18.1
      - flake8==3.9.2
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - lxml==5.3.1
      - markupsafe==2.0.1
      - mccabe==0.6.1
      - mock==5.2.0
      - nose==1.3.7
      - packaging==21.3
      - paramiko==3.5.1
      - pluggy==1.0.0
      - py==1.11.0
      - pycodestyle==2.7.0
      - pycparser==2.21
      - pyflakes==2.3.1
      - pygments==2.14.0
      - pynacl==1.5.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pytz==2025.2
      - requests==2.27.1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/ncclient

test/unit/test_xml_.py::TestXML::test_sub_ele_inherit_parent_namespace
test/unit/test_xml_.py::Test_NCElement::test_ncelement_reply_001 test/unit/test_xml_.py::Test_NCElement::test_ncelement_reply_002 test/unit/test_xml_.py::Test_NCElement::test_ncelement_reply_003 test/unit/test_xml_.py::TestXML::test_ncelement_find test/unit/test_xml_.py::TestXML::test_ncelement_findtext test/unit/test_xml_.py::TestXML::test_ncelement_remove_namespace test/unit/test_xml_.py::TestXML::test_ncelement_reply_001 test/unit/test_xml_.py::TestXML::test_parse_root test/unit/test_xml_.py::TestXML::test_to_ele test/unit/test_xml_.py::TestXML::test_validated_element_fail test/unit/test_xml_.py::TestXML::test_validated_element_fail_2 test/unit/test_xml_.py::TestXML::test_validated_element_fail_3 test/unit/test_xml_.py::TestXML::test_validated_element_pass
ncclient/xml_.py
ncclient/xml_.py