1

我正在尝试将 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

4 回答 4

1

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

于 2010-02-05T21:46:55.570 回答
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)

这对我来说已经足够好了:)

于 2010-02-06T17:05:09.703 回答
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 文本。

于 2010-09-12T16:44:45.203 回答
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)

对于 minidom,由于每个节点都伴随着一个尾随空白节点,所以它有点复杂:

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')
于 2020-02-03T17:39:25.210 回答