簡體   English   中英

使用lxml解析具有多個xml文檔的文件

[英]Parse file with several xml documents using lxml

因此,我認為這是一個非常典型的用例,但是我真的無法在lxml文檔中找到有關對此的任何支持。 基本上,我有一個xml文件,其中包含許多不同的xml文檔(尤其是審閱)。該結構大致為:

<review>
    <!-- A bunch of metadata -->
</review>
<!-- The issue is here -->
<review>
    <!-- A bunch of metadata -->
</review>

基本上,我嘗試像這樣讀取文件:

import lxml

document = lxml.etree.fromstring(open(xml_file).read())

但這樣做時會出現錯誤:

lxml.etree.XMLSyntaxError: Extra content at the end of the document

完全合理的錯誤,實際上是xml錯誤,應將其視為此類錯誤,但是我的問題是:如何使lxml識別這是xml文檔列表並據此進行解析?

list_of_reviews = lxml.magic(open(xml_file).read())

magic是真正的lxml函數嗎?

因此,這有點笨拙,但應該相對可靠。 這里有兩個主要的負面因素:

  • 重復調用fromstring意味着此代碼不是非常快。 大約與單獨解析每個文檔相同的速度,比所有文檔都慢得多
  • 相對於文檔中的當前位置會引發錯誤。 添加相對位置支持會很容易(只需添加一個累加器來跟蹤當前位置)

基本上,方法是查找引發的錯誤,然后僅分析錯誤上方的文件部分。 如果引發了與根節點的最后一個無關的錯誤,則將其作為典型異常進行處理。

def fix_xml_list(test_file):
    documents = []
    finished = False
    while not finished:
        try:
            lxml.etree.fromstring(test_file)
        except XMLSyntaxError as e:
            if e.code == 5 and e.position[1] == 1:
                doc_end = e.position[0]
                end_char = find_nth(test_file, '\n', doc_end - 2)
                documents.append(lxml.etree.fromstring(test_file[:end_char]))
                if end_char == len(test_file):
                    finished = True
                test_file = test_file[end_char:]
            else:
                print e
                break
    return documents

def find_nth(doc, search, n=0):
    l = len(search)
    i = -l
    for c in xrange(n + 1):
        i = doc.find(search, i + l)
        if i < 0:
            break
    return i

find_nth代碼被從這個問題中find_nth偷走了。 可能沒有很多情況可以使用此代碼,但是對我來說,有大量稍微不規則的文檔(在學術數據中很常見),這是非常寶貴的。

XML文檔必須具有一個根元素。 否則,它們格式不正確,並且實際上不是XML。 合格的解析器無法解析格式不正確的“ XML”。

從多個文檔構造單個XML文檔時,只需將不同的根元素包裝在一個根元素中。 然后,您將能夠使用標准解析器,例如lxml。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM