阅读与使用Python的ElementTree多个顶级项目XML?
-
22-09-2019 - |
题
我如何读取使用Python ElementTree的XML文件,如果XML有多个顶级项目?
我有一个XML文件,我想使用Python ElementTree的阅读。
不幸的是,它有多个顶级标签。我想包<doc>...</doc>
围绕XML,但我必须把<doc>
之后的<?xml>
和<!DOCTYPE>
领域。但搞清楚<!DOCTYPE>
端部是不平凡的。
什么我有:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FOO BAR "foo.dtd" [
<!ENTITY ...>
<!ENTITY ...>
<!ENTITY ...>
]>
<ARTICLE> ... </ARTICLE>
<ARTICLE> ... </ARTICLE>
<ARTICLE> ... </ARTICLE>
<ARTICLE> ... </ARTICLE>
我想什么:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE FOO BAR "foo.dtd" [
<!ENTITY ...>
<!ENTITY ...>
<!ENTITY ...>
]>
<DOC>
<ARTICLE> ... </ARTICLE>
<ARTICLE> ... </ARTICLE>
<ARTICLE> ... </ARTICLE>
<ARTICLE> ... </ARTICLE>
</DOC>
NB标签物品的名称可能会改变,所以我不能用grep吧。
任何人都可以建议我怎么可以在XML头后添加封闭<doc>...</doc>
,或建议另一种解决方法吗?
解决方案
我写下面的函数来添加一个顶级标签的后强>的XML处理指令。现在,您可以找到自己的共同Python库作为的 common.myelementtree.add_toplevel_tag
import re
xmlprocre = re.compile("(\s*<[\?\!])")
def add_toplevel_tag(string):
"""
After all the XML processing instructions, add an enclosing top-level <DOC> tag, and return it.
e.g.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE FOO BAR "foo.dtd" [ <!ENTITY ...> <!ENTITY ...> <!ENTITY ...> ]> <ARTICLE> ...
</ARTICLE> <ARTICLE> ... </ARTICLE> <ARTICLE> ... </ARTICLE> <ARTICLE> ... </ARTICLE>
=>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE FOO BAR "foo.dtd" [ <!ENTITY ...> <!ENTITY ...> <!ENTITY ...> ]><DOC> <ARTICLE> ...
</ARTICLE> <ARTICLE> ... </ARTICLE> <ARTICLE> ... </ARTICLE> <ARTICLE> ... </ARTICLE></DOC>
"""
def _advance_proc(string, idx):
# If possible, advance over whitespace and one processing
# instruction starting at string index idx, and return its index.
# If not possible, return None
# Find the beginning of the processing instruction
m = xmlprocre.match(string[idx:])
if m is None: return None
#print "Group", m.group(1)
idx = idx + len(m.group(1))
#print "Remain", string[idx:]
# Find closing > bracket
bracketdebt = 1
while bracketdebt > 0:
if string[idx] == "<": bracketdebt += 1
elif string[idx] == ">": bracketdebt -= 1
idx += 1
#print "Remain", string[idx:]
return idx
loc = 0
while 1:
# Advance one processing instruction
newloc = _advance_proc(string, loc)
if newloc is None: break
else: loc = newloc
return string[:loc] + "<DOC>" + string[loc:] + "</DOC>"
不隶属于 StackOverflow