Python xml.dom.minidom removeChild空白问题

时间:2010-02-05 21:16:48

标签: python xml whitespace removechild

我正在尝试将xml文件读入python,从xml文件中提取某些元素,然后将结果写回xml文件(所以基本上它是没有多个元素的原始xml文件)。当我使用.removeChild(source)时,它会删除我想要删除的单个元素,但会留下空格,使文件非常难以理解。我知道我仍然可以使用所有空格解析文件,但有时我需要手动更改某些元素属性的值,这使得执行此操作变得困难(并且很难)。我当然可以手工删除空白,但如果我有几十个这些xml文件并不可行。

有没有办法做.removeChild并让它删除空格?

以下是我的代码:

dom=parse(filename)
main=dom.childNodes[0]
sources = main.getElementsByTagName("source")
for source in sources :
    name=source.getAttribute("name")
    spatialModel=source.getElementsByTagName("spatialModel")
    val1=float(spatialModel[0].getElementsByTagName("parameter")[0].getAttribute("value"))
    val2=float(spatialModel[0].getElementsByTagName("parameter")[1].getAttribute("value"))
    if angsep(val1,val2,X,Y)>=ROI :
        main.removeChild(source)
    else:
        print name,val1,val2,angsep(val1,val2,X,Y)
f=open(outfile,"write")
f.write("<?xml version=\"1.0\" ?>\n")
f.write(dom.saveXML(main))
f.close()

非常感谢你的帮助。

4 个答案:

答案 0 :(得分:1)

如果安装了PyXML,可以使用xml.dom.ext.PrettyPrint()

答案 1 :(得分:1)

我无法弄清楚如何使用xml.dom.minidom执行此操作,因此我只是编写了一个快速函数来读取输出文件并删除所有空白行,然后重写为新文件:

f = open(xmlfile).readlines()
w = open('src_model.xml','w')
empty=re.compile('^$')
for line in open(xmlfile).readlines():
    if empty.match(line):
        continue
    else: 
        w.write(line)

这对我来说足够好:))

答案 2 :(得分:1)

...搜索ppl:

这个有趣的片段

skey = lambda x: getattr(x, "tagName", None)
mainnode.childNodes = sorted( 
  [n for n in mainnode.childNodes if n.nodeType != n.TEXT_NODE],
  cmp=lambda x, y: cmp(skey(y), skey(x)))

删除所有文本节点(并且,反过来按标记名对它们进行排序)。

即。您可以(递归地)执行tr.childNodes = [recurseclean(n) for n in tr.childNodes if n.nodeType != n.TEXT_NODE]删除所有文本节点

或者你可能想做… if n.nodeType != n.TEXT_NODE or not re.match(r'^[:whitespace:]*$', n.data, re.MULTILINE)之类的事情(如果你需要带有一些数据的文本节点,我自己也不会尝试那个)。或者将文本留在特定标签内的更复杂的东西。

之后tree.toprettyxml(…)将返回格式良好的XML文本。

答案 3 :(得分:0)

我知道,这个问题已经过时了,但是由于花了一些时间来找出解决问题的不同方法,所以下面是我的解决方案:

我发现最好的方法确实是使用lxml:

from lxml import etree

root = etree.fromstring(data)
# for tag in root.iter('tag') doesn't cope with namespaces...
for tag in root.xpath('//*[local-name() = "tag"]'):
    tag.getparent().remove(tag)
data = etree.tostring(root, encoding = 'utf-8', pretty_print = True)

在最小化的情况下,由于每个节点都带有尾随空白节点这一事实,使得问题更加复杂:

import xml.dom.minidom

dom = xml.dom.minidom.parseString(data)
for tag in dom.getElementsByTagName('tag'):
    if tag.nextSibling \
            and tag.nextSibling.nodeType == meta.TEXT_NODE \
            and tag.nextSibling.data.isspace():
        tag.parentNode.removeChild(tag.nextSibling)
    tag.parentNode.removeChild(tag)
data = dom.documentElement.toxml(encoding = 'utf-8')