2

Is it possible to comment out an xml element with python's lxml while preserving the original element rendering inside the comment? I tried the following

elem.getparent().replace(elem, etree.Comment(etree.tostring(elem, pretty_print=True)))

but tostring() adds the namespace declaration.

BlindDriver
  • 627
  • 3
  • 14
  • What namespace declaration? Please provide a [mcve]. – mzjn Jun 10 '17 at 09:11
  • mzjn: xmlns="foo" etc. In the original xml these declarations are inherited from the root element and are not explicitly present in the children. tostring(), of course, doesn't know that. – BlindDriver Jun 12 '17 at 15:09
  • 1
    OK, I understand. But I still think that it is reasonable to request a complete example that demonstrates the problem. Now I have provided an example in my answer. – mzjn Jun 12 '17 at 17:12

1 Answers1

3

The namespace of the commented-out element is inherited from the root element. Demo:

from lxml import etree

XML = """
<root xmlns='foo'>
 <a>
  <b>AAA</b>
 </a>
</root>"""

root = etree.fromstring(XML)
b = root.find(".//{foo}b")
b.getparent().replace(b, etree.Comment(etree.tostring(b)))
print etree.tostring(root)

Result:

<root xmlns="foo">
 <a>
  <!--<b xmlns="foo">AAA</b>
 --></a>
</root>

Manipulating namespaces is often harder than you might suspect. See https://stackoverflow.com/a/31870245/407651.

My suggestion here is to use BeautifulSoup, which in practice does not really care about namespaces (soup.find('b') returns the b element even though it is in the foo namespace).

from bs4 import BeautifulSoup, Comment

soup = BeautifulSoup(XML, "xml")
b = soup.find('b')
b.replace_with(Comment(str(b)))
print soup.prettify()

Result:

<?xml version="1.0" encoding="utf-8"?>
<root mlns="foo">
 <a>
  <!--<b>AAA</b>-->
 </a>
</root>
mzjn
  • 48,958
  • 13
  • 128
  • 248