简体   繁体   中英

Comment xml sections in Python

I have an XML file that is containing several sections and I would need to comment 2 of them. The file is like this:

<web-app>
  <display-name>Web Application</display-name>
  <context-param>
      <param-name>defaultContext</param-name>
      <param-value>true</param-value>
  </context-param>
  <listener>
      <listener-class>MyListener</listener-class>
  </listener>
  <filter>
      <filter-name>Filter1</filter-name>
      <filter-class>filter.Filter1</filter-class>
      <init-param>
        <param-name>type</param-name>
        <param-value>JSP</param-value>
      </init-param>
  </filter>
  <filter>
      <filter-name>Filter2</filter-name>
      <filter-class>filter.Filter2</filter-class>
      <init-param>
        <param-name>type</param-name>
        <param-value>HTM</param-value>
      </init-param>
  </filter>
  <filter>
      <filter-name>Filter3</filter-name>
      <filter-class>filter.Filter3</filter-class>
  </filter>
</web-app>

In this example I need to comment the Filter1 and Filter3 sections. But it could be any of them, and not in a particular order, so I need to match the good section to be commented based on the filter name. So the updated file would be:

<web-app>
  <display-name>Web Application</display-name>
  <context-param>
      <param-name>defaultContext</param-name>
      <param-value>true</param-value>
  </context-param>
  <listener>
      <listener-class>MyListener</listener-class>
  </listener>
  <!--filter>
      <filter-name>Filter1</filter-name>
      <filter-class>filter.Filter1</filter-class>
      <init-param>
        <param-name>type</param-name>
        <param-value>JSP</param-value>
      </init-param>
  </filter-->
  <filter>
      <filter-name>Filter2</filter-name>
      <filter-class>filter.Filter2</filter-class>
      <init-param>
        <param-name>type</param-name>
        <param-value>HTM</param-value>
      </init-param>
  </filter>
  <!--filter>
      <filter-name>Filter3</filter-name>
      <filter-class>filter.Filter3</filter-class>
  </filter-->
</web-app>

I have started to check the xml.dom.minidom to do this, but in fact I don't know how to locate precisely the Filter1 and Filter3 and how to comment the whole section including those two elements. Basically I have started this code:

from xml.dom import minidom

#Method to comment a node
def comment_node(node):
    comment = node.ownerDocument.createComment(node.toxml())
    node.parentNode.replaceChild(comment, node)
    return comment

#Parse the web.xml file
current_path = getcwd()
relative_file_path = r"webapp\WEB-INF\web.xml"
file_path = normpath(join(current_path, relative_file_path))
dom = minidom.parse(file_path)

#Search for filter sections
itemlist = dom.getElementsByTagName('filter-name')
for item in itemlist:
    if "Filter1" == item.nodeValue:
        #need to comment the whole node containing the filter-name

This is where I'm stuck. Shall I search for all nodes 'filter' and then check if each one of them contains the good filter-name insead?

Please note that I am a beginner in Python, so I don't even know if I picked-up the good library here...

Could anyone help me to think of the good strategy to apply the change?

Thanks!

Just little modification

itemlist = dom.getElementsByTagName('filter-name')
for item in itemlist:
    if "Filter1" == item.childNodes[0].nodeValue:
        #need to comment the whole node containing the filter-name
        comment_node(item.parentNode)
print dom.toxml() # verif

Just in case of, here is the final version of my code. I added the writing to the xml file as it needs to be done manually (I thought in the beginning that the methods of the API where kind of pointers, so that the file was automatically updated!):

from os import getcwd
from os.path import normpath, join
from xml.dom import minidom

#Script explanation to the user
print("This script updates the web.xml file")
print()

#Method to comment a node
def comment_node(node):
    comment = node.ownerDocument.createComment(node.toxml())
    node.parentNode.replaceChild(comment, node)

#Parse the web.xml file
current_path = getcwd()
relative_file_path = r"webapp\WEB-INF\web.xml"
file_path = normpath(join(current_path, relative_file_path))
dom = minidom.parse(file_path)

#Search for filter sections
itemlist = dom.getElementsByTagName('filter')
for item in itemlist:
    for sub_item in item.childNodes:
        if "filter-name" == sub_item.nodeName:
            if "Filter1" == sub_item.childNodes[0].nodeValue or "Filter3" == sub_item.childNodes[0].nodeValue:
                #Need to comment the whole node containing the filter-name
                comment_node(item)
                #Stop looping on all the sub items as we already found the filter-name node
                break

# Should you want to see the result
print("Resulting file:")
print(dom.toxml())

#Writing to the file
file = open(file_path, 'w')
dom.writexml(file)
file.close()

Thanks a lot to @David Zemens and @djangoliv for their valuable help!

Update

Update suggested by @djangoliv, thanks!:

#itemlist = dom.getElementsByTagName('filter')
#for item in itemlist:
#   for sub_item in item.childNodes:
#       if "filter-name" == sub_item.nodeName:
#           if "Filter1" == sub_item.childNodes[0].nodeValue or "Filter3" == sub_item.childNodes[0].nodeValue:
#               #Need to comment the whole node containing the filter-name
#               comment_node(item)
#               #Stop looping on all the sub items as we already found the filter-name node
#               break
# more simple
itemlist = dom.getElementsByTagName('filter-name')
for item in itemlist:
    if item.childNodes[0].nodeValue in ["Filter1", "Filter3"]:
        comment_node(item.parentNode)
        break

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM