【问题标题】:Read XML with multiple top-level items using Python ElementTree?使用 Python ElementTree 读取具有多个顶级项目的 XML?
【发布时间】:2011-01-08 00:01:25
【问题描述】:

如果 XML 有多个顶级项,我如何使用 Python ElementTree 读取 XML 文件?

我有一个想要使用 Python ElementTree 读取的 XML 文件。

不幸的是,它有多个顶级标签。我会将<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>

注意,标签 ARTICLE 的名称可能会改变,所以我无法 grep。

谁能向我建议如何在 XML 标头之后添加封闭的 &lt;doc&gt;...&lt;/doc&gt;,或者建议另一种解决方法?

【问题讨论】:

    标签: python xml parsing elementtree


    【解决方案1】:

    我写了以下函数来在XML处理指令之后添加一个顶级标签。您现在可以在我的common Python library 中找到此代码为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>"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多