【问题标题】:how to remove specifc tags in xml using python如何使用python删除xml中的特定标签
【发布时间】:2015-11-28 00:41:01
【问题描述】:

我必须删除 apache-tomcat web.xml 文件中的一些特定标签

web.xml

    <?xml version="1.0" encoding="ISO-8859-1"?>



<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">

  <!-- ======================== Introduction ============================== -->
  <!-- This document defines default values for *all* web applications      -->
  <!-- loaded into this instance of Tomcat.  As each application is         -->
  <!-- deployed, this file is processed, followed by the                    -->
  <!-- "/WEB-INF/web.xml" deployment descriptor from your own               -->
  <!-- applications.                                                        -->
  <!--                                                                      -->
  <!-- WARNING:  Do not configure application-specific resources here!      -->
  <!-- They should go in the "/WEB-INF/web.xml" file in your application.   -->

     <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
   <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>cgi</servlet-name>
        <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
        <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
        </init-param>
        <init-param>
          <param-name>cgiPathPrefix</param-name>
          <param-value>WEB-INF/cgi</param-value>
        </init-param>
         <load-on-startup>5</load-on-startup>
    </servlet>
</<web-app>

如果 servlet-name== cgi 我需要删除整个 servlet 标记。 我的代码如下:

    from xml.etree.ElementTree import ElementTree
    tree = ElementTree()
    tree.parse('web.xml')
    servlets = tree.findall('servlet')
    print "servlets : ",servlets
    for servlet in servlets:
      servlet_names = foo.findall('servlet-name')
      for servlet_name  in servlet_names:
            if servlet_name == "cgi" :
                    print "servlet_name :", servlet_name
                    servlet.remove(servlet-name)

我得到 o/p 作为 servlet :[] 而不是所有的 servlet 并且无法进入 for 循环。 谁能帮帮我?。

我没有得到任何异常

#!/usr/bin/python
from xml.etree.ElementTree import ElementTree
tree = ElementTree()
tree.parse('web.xml')
root = tree.getroot()
ns = '{http://java.sun.com/xml/ns/javaee}'
servlets = root.findall(ns + 'servlet')
print "servlets : ",servlets
for servlet in servlets:
  servlet_names = servlet.findall(ns + 'servlet-name')
  for servlet_name  in servlet_names:
        if servlet_name.text == "cgi" :
                print "servlet_name :", servlet_name.text
                print "removed the cgi serverlet", root.remove(servlet)

=====输出================ servlet : [http://java.sun.com/xml/ns/javaee}servlet at 7f84e09b35a8>, http://java.sun.com/xml/ns/javaee}servlet at 7f84e09b3878>, http://java .sun.com/xml/ns/javaee}servlet 在 7f84e09b3bd8>] servlet_name:cgi 删除了 cgi serverlet 无

==== 我已经使用 pdb 跟踪器来找出元素(servlet)的值,它显示为 \n..

> /apps/manu/python/manunamespace.py(10)<module>()
-> servlet_name=servlet.find('{http://java.sun.com/xml/ns/javaee}servlet-name')
(Pdb) servlet_name
<Element {http://java.sun.com/xml/ns/javaee}servlet-name at 882878>
(Pdb) servlet_name.text
'jsp'
(Pdb) n
> /apps/manu/python/manunamespace.py(11)<module>()
-> print "servlet_name:", servlet_name.text
(Pdb) servlet_name.text
'cgi'
(Pdb) servlet.text
'\n        '
(Pdb) n
servlet_name: cgi
> /apps/manu/python/manunamespace.py(12)<module>()
-> if servlet_name.text == "cgi":
(Pdb) n
> /apps/manu/python/manunamespace.py(13)<module>()
-> print "remove the element"
(Pdb) n
remove the element
> /apps/manu/python/manunamespace.py(14)<module>()
-> print "remove : ",root.remove(servlet)
(Pdb) servlet
<Element {http://java.sun.com/xml/ns/javaee}servlet at 882d88>
(Pdb) servlet.text
'\n 

   '

【问题讨论】:

  • 您只是没有打印更改后的树,只有root.remove 的结果,即None。该代码有效,您只需要在修改它后对树做一些事情。要打印它,您可以使用tree.write(sys.stdout)treee.write(open('filename', 'w')) 将其写入文件。
  • 得到它并且它现在可以工作了,但是当我写入文件时它无法写入名称空间并排除文件中的所有 cmets。

标签: python xml


【解决方案1】:

这失败了:

servlets = tree.findall('servlet')

因为您的文档中没有 servlet 元素。根元素指定:

xmlns="http://java.sun.com/xml/ns/javaee"

这意味着所有元素,除非另有说明,都在这个 XML 命名空间中。所以你想要:

>>> tree.findall('{http://java.sun.com/xml/ns/javaee}servlet')
[<Element {http://java.sun.com/xml/ns/javaee}servlet at 0x7f280ec681b8>,
<Element {http://java.sun.com/xml/ns/javaee}servlet at 0x7f280ec68200>, 
<Element {http://java.sun.com/xml/ns/javaee}servlet at 0x7f280ec682d8>]
>>> 

【讨论】:

    【解决方案2】:

    您没有找到要搜索的标签,因为它们位于默认命名空间 (http://java.sun.com/xml/ns/javaee) 中。

    另外,如果你想测试一个元素的内容,你需要使用它的text 属性,而不是与元素本身进行比较。如果匹配,则需要从根目录中删除 servlet-tag,而不是 servlet 中的 servlet-name 标记。

    试试这个:

    from xml.etree.ElementTree import ElementTree
    tree = ElementTree()
    tree.parse('web.xml')
    root = tree.getroot()
    nsmap = {'jee': 'http://java.sun.com/xml/ns/javaee'}
    servlets = root.findall('jee:servlet', nsmap)
    print "servlets : ",servlets
    for servlet in servlets:
      servlet_names = servlet.findall('jee:servlet-name', nsmap)
      for servlet_name  in servlet_names:
            if servlet_name.text == "cgi" :
                    print "servlet_name :", servlet_name.text
                    root.remove(servlet)
    

    或者更有效地使用supported xpath syntax

    from xml.etree.ElementTree import ElementTree
    tree = ElementTree()
    tree.parse('web.xml')
    root = tree.getroot()
    nsmap = {'jee': 'http://java.sun.com/xml/ns/javaee'}
    for servlet in root.findall("./jee:servlet[jee:servlet-name='cgi']", nsmap):
        root.remove(servlet)
    

    编辑:对于较旧的python版本(用python2.5测试):

    from xml.etree.ElementTree import ElementTree
    tree = ElementTree()
    tree.parse('web.xml')
    root = tree.getroot()
    ns = '{http://java.sun.com/xml/ns/javaee}'
    servlets = root.findall(ns + 'servlet')
    print "servlets : ",servlets
    for servlet in servlets:
      servlet_names = servlet.findall(ns + 'servlet-name')
      for servlet_name  in servlet_names:
            if servlet_name.text == "cgi" :
                    print "servlet_name :", servlet_name.text
                    root.remove(servlet)
    

    【讨论】:

    • 能够看到以下两种情况的异常:1)root.findall('jee:servlet',nsmap)中的servlet:TypeError:findall()恰好需要2个参数(3个给定)Scanario 2) :r servlet in root.findall("./jee:servlet[jee:servlet-name='cgi']", nsmap): 。你能建议可能是什么问题吗
    • 下面的代码正在运行,但无法删除该元素。 import xml.etree.ElementTree as ET tree = ET.parse('web.xml') root = tree.getroot() #root = ET.fromstring('web.xml') for servlet in root.findall('{@ 987654322@}servlet'): print "servlet : ", servlet.text servlet_name=servlet.find('{java.sun.com/xml/ns/javaee}servlet-name') print "servlet_name:", servlet_name.text if servlet_name.text == "cgi ": print "删除元素" root.remove(servlet) print "servlet", servlet.text
    • 您可能使用的是过时的python版本(2.6或更早版本),它不支持名称空间前缀或findall的扩展语法...如果您无法更新python,请使用第一个具有完整命名空间语法的变体(将 jee: 替换为 {http://java.sun.com/xml/ns/javaee}
    • 好的,玛塔。但我无法删除上面定义的元素。
    • 当然你还需要去掉 nsmap 参数。添加了在 python2.5 上工作的完整示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    相关资源
    最近更新 更多