0

I'm trying (and failing) to comment out the HornetQ configuration from a JBoss 6.2 domain.xml file, instead of inserting a comment around the stanza I want to remove, I'm managing to delete everything remaining in the file.

The code I have so far is

from xml.dom import minidom
import os, time, shutil

domConf=('/home/test/JBoss/jboss-eap-6.2/domain/configuration/domain.xml')
commentSub=('urn:jboss:domain:messaging:1.4')


now=str(int(time.time())) 
bkup=(domConf+now)
shutil.copy2(domConf, bkup)

xmldoc = minidom.parse(domConf)
itemlist = xmldoc.getElementsByTagName('subsystem')
for s in itemlist:
        if commentSub in s.attributes['xmlns'].value:
            s.parentNode.insertBefore(xmldoc.createComment(s.toxml()), s)
file = open(domConf, "wb")
xmldoc.writexml(file)
file.write('\n')
file.close()

the configuration I'm trying to comment out is -

        <subsystem xmlns="urn:jboss:domain:messaging:1.4">
            <hornetq-server>
                <persistence-enabled>true</persistence-enabled>
                <journal-type>NIO</journal-type>
                <journal-min-files>2</journal-min-files>
                <connectors>
[....]
                    </pooled-connection-factory>
                </jms-connection-factories>
            </hornetq-server>
        </subsystem>

Thanks!

BenH
  • 45
  • 6
  • Please make it clear that what is the raw file and what do you expect to output? – Timothy Dec 19 '13 at 21:45
  • The domain.xml file is >30K in size so not much point in posting the whole thing, however what I'm attempting to do is find the XML stanza containing urn:jboss:domain:messaging:1.4 and then insert a comment around the whole thing, so – BenH Dec 20 '13 at 00:36

1 Answers1

1

The problem you were running into was that the sections you are trying to comment out already contain XML comments. Nested comments are not allowed in XML. (See Nested comments in XML? for more info.)

I think what you need to do is this:

from xml.dom import minidom
import os, time, shutil

domConf=('/home/test/JBoss/jboss-eap-6.2/domain/configuration/domain.xml')
resultFile='result.xml'
commentSub=('urn:jboss:domain:messaging:1.4')

now=str(int(time.time()))
bkup=(domConf+now)
shutil.copy2(domConf, bkup)

xmldoc = minidom.parse(domConf)
itemlist = xmldoc.getElementsByTagName('subsystem')
for s in itemlist:
        if commentSub in s.attributes['xmlns'].value:
            commentText = s.toxml()
            commentText = commentText.replace('--', '- -')
            s.parentNode.insertBefore(xmldoc.createComment(commentText), s)
            s.parentNode.removeChild(s)
file = open("result.xml", "wb")
xmldoc.writexml(file)
file.write('\n')
file.close()

shutil.copy2(resultFile, domConf)

This finds the comment as you do, but before inserting it, changes any nested XML comments so they are no longer comments by replacing '--' with '- -'. (Note this will probably break the XML file structure if you uncomment that section. You'll have to reverse the process if you want it to parse again.) After inserting, the script deletes the original node. Then it writes everything to a temporary file, and uses shutil to copy it back over the original.

I tested this on my system, using the file you posted to the pastebin in the comment below, and it works.

Note that it's kind of a quick and dirty hack - because the script will also replace '--' with '- -' everywhere in that section, and if there is other text as part of an XML node that has '--' in it, it too will get replaced...

The right way to do this would probably be to use lxml's elementtree implementation, use lxml's XSL to select only comments within the section, and either delete or transform them appropriately - so you don't mess up non-commented text. But that's probably beyond the scope of what you asked. (Python's built-in elementtree doesn't have a complete XSL implementation and probably can't be used to select comments.)

Community
  • 1
  • 1
Adam F
  • 1,151
  • 1
  • 11
  • 16
  • Thanks but it didnt work on the config file and deleted the remainder of the file, although running it with some debugging does produce this error - xmldoc.writexml(file) File "/usr/lib/python2.7/xml/dom/minidom.py", line 1752, in writexml File "/usr/lib/python2.7/xml/dom/minidom.py", line 1138, in writexml [...] raise ValueError("'--' is not allowed in a comment node") ValueError: '--' is not allowed in a comment node Which suggests that its the writing out of the document failing that is the actual problem! – BenH Dec 20 '13 at 10:09
  • If you put the actual config file in a pastebin (http://pastebin.com/) and post a link here, I'll take a look. – Adam F Dec 20 '13 at 16:00
  • The problem is that there is an XML comment in each of the two sections you are commenting out. You can't next XML comments, for more information see this answer for more info: http://stackoverflow.com/questions/1324821/nested-comments-in-xml There is a way to get this to work, though, by changing the inner comments - I'll update my answer with that. – Adam F Dec 20 '13 at 20:37
  • This I did not know! Thank you! – BenH Dec 20 '13 at 23:15