Python xml.dom.minidom 删除子节点的空白问题

1 投票
4 回答
8768 浏览
提问于 2025-04-15 18:56

我正在尝试把一个xml文件读入到Python中,从中提取一些特定的元素,然后再把结果写回到一个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 个回答

1

… 用于搜索人:

这个有趣的小代码片段

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文本。

1

如果你安装了PyXML这个库,你就可以使用xml.dom.ext.PrettyPrint()这个功能。

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)

这个方法对我来说效果还不错 :)

撰写回答