【发布时间】:2016-06-23 22:37:43
【问题描述】:
我想删除某个标签值的元素,然后写出.xml文件,而这些删除的元素没有任何标签;是我创建新树的唯一选择吗?
移除/删除元素有两种选择:
clear() 重置元素。此功能删除所有子元素,清除所有 属性,并将 text 和 tail 属性设置为 None。
起初我使用它,它的目的是从元素中删除 数据,但我仍然留下一个空元素:
# Remove all elements from the tree that are NOT "job" or "make" or "build" elements
log = open("debug.log", "w")
for el in root.iter(*):
if el.tag != "job" and el.tag != "make" and el.tag != "build":
print("removed = ", el.tag, el.attrib, file=log)
el.clear()
else:
print("NOT", el.tag, el.attrib, file=log)
log.close()
tree.write("make_and_job_tree.xml", short_empty_elements=False)
问题是xml.etree.ElementTree.ElementTree.write()still writes out empty tags no matter what:
...仅关键字的 short_empty_elements 参数控制 不包含内容的元素的格式。如果为真(默认), 它们作为单个自封闭标签发出,否则它们是 作为一对开始/结束标签发出。
为什么不能选择不打印那些空标签!随便。
所以我想我可以试试
remove(subelement) 从元素中移除子元素。与 find* 方法不同,这 方法基于实例标识而不是标签来比较元素 价值或内容。
但这仅对子元素起作用。
所以我必须do something like:
for el in root.iter(*):
for subel in el:
if subel.tag != "make" and subel.tag != "job" and subel.tag != "build":
el.remove(subel)
但是这里有一个大问题:我通过删除元素来使迭代器无效,对吧?
通过添加if subel来简单检查元素是否为空就足够了吗?:
if subel and subel.tag != "make" and subel.tag != "job" and subel.tag != "build"
还是每次我使树元素无效时都必须为树元素获取一个新的迭代器?
记住:我只是想为空元素写出没有标签的 xml 文件。
这是一个例子。
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
假设我想删除任何提及neighbor。
理想情况下,我希望在删除后得到这个输出:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
</country>
</data>
问题是,当我使用 clear() 运行代码(参见上面的第一个代码块)并将其写入文件时,我得到了这个:
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor></neighbor><neighbor></neighbor></country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor></neighbor></country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor></neighbor><neighbor></neighbor></country>
</data>
通知neighbor 仍然出现。
我知道我可以轻松地在输出上运行正则表达式,但必须有一种方法(或另一个 Python api)可以即时执行此操作,而不是要求我再次触摸我的 .xml 文件。
【问题讨论】:
-
你能添加一个你的xml样本和你想要的输出吗?你也愿意使用 lxml 吗?
-
@PadraicCunningham 如果
lxml在 Python 中,是的。我不在乎我使用哪个 API。我会在我要查找的内容之前和之后进行更新。 -
是否需要python?
-
@vtd-xml-author 没有。我只是选择了 Python,因为调试很简单,而且我已经使用过它。你有什么想法?
-
@PadraicCunningham 如何让this question 链接到我的问题?这是回答我的问题的问题。编辑:实际上没有回答。仅仅解释了一种方法是无效的。