簡體   English   中英

使用Python 3將XML導入SQLite3數據庫

[英]Getting XML into a SQLite3 database using Python 3

我一直在嘗試使用ElementTree將數據從指定的XML文件獲取到SQLite3數據庫中。 XML具有以下結構:

<?xml version="1.0" encoding="UTF-8" ?>
<chat xmlns="http://test.org/net/1.3">
    <event sender="Frank" time="2016-02-03T22:58:19+01:00" />
    <message sender="Karen" time="2016-02-03T22:58:19+01:00">
        <div>
            <span>Hello Frank</span>
        </div>
    </message>
    <message sender="Frank" time="2016-02-03T22:58:39+01:00">
        <div>
            <span>Hi there Karen</span>
        </div>
        <div>
            <span>I'm back from New York</span>
        </div>
    </message>
    <message sender="Karen" time="2016-02-03T22:58:56+01:00">
        <div>
            <span>How are you doing?</span>
            <span>Everything OK?</span>
        </div>
    </message>
</chat>

對於每個消息或事件,我在數據庫中創建一個記錄,其中包含以下幾列:發件人,時間,消息。 以下代碼用於處理XML:

import xml.etree.ElementTree as ET
import sqlite3 as lite

con = None
con = lite.connect('dbtest.db')
cur = con.cursor()

xmlfile = 'test.xml'

tree = ET.parse(xmlfile)
root = tree.getroot()

for m in root.findall('./*'):
    msg = m.find('.')
    msg.tag = 'div'

    sender = str(m.get('sender'))
    time = m.get('time')
    message = str(ET.tostring(msg))

    print('Sender: ' + sender)
    print('Time: ' + time)
    print('HTML: ' + message)
    print()

    query = ("INSERT INTO chat('time', 'sender', 'message') VALUES(?,?,?)")
    values = (time, sender, message)

    with con:
        cur = con.cursor()
        cur.execute(query, values)

if con:
    con.close()

這導致幾個問題。

首先,我沒有得到想要的結果。 “消息”應該是message標記中的內容,不包括封閉的message標記,現在已將其重命名為div 這是我應該得到的:

<div>
    <span>Hi there Karen</span>
</div>
<div>
    <span>I'm back from New York</span>
</div>

也許這樣:

<div><span>Hi there Karen</span></div><div><span>I'm back from New York</span></div>

相反,我得到這個:

b'<div xmlns:ns0="http://test.org/net/1.3" sender="Karen" time="2016-02-03T22:58:19+01:00">\n\t\t<ns0:div>\n\t\t\t<ns0:span>Hello Frank</ns0:span>\n\t\t</ns0:div>\n\t</div>\n\t'

因此,我嘗試通過刪除b'等來“修復”此問題,但我希望有更好的方法。 並刪除開頭的b'有效,但是我無法使用字符串替換擺脫\\t\\n

如何在沒有所有轉義字符的情況下將正確的XML數據放入表中?

因此,ElementTree.tostring默認情況下返回字節對象,而不是字符串。 因此,當您將其打印出來時,您所期望和想要的是字符串時,就會看到該字節對象的序列化形式。 我沒有研究它,但是我懷疑sqlite綁定會將字節對象作為BLOB插入,並將字符串作為TEXT值插入數據庫,並且逐字節地最終它們是相同的。

無論如何,以您想要的更易於閱讀的形式打印xml:

import xml.etree.ElementTree as ET

rawxml='''<?xml version="1.0" encoding="UTF-8" ?>
<chat xmlns="http://test.org/net/1.3">
    <event sender="Frank" time="2016-02-03T22:58:19+01:00" />
    <message sender="Karen" time="2016-02-03T22:58:19+01:00">
        <div>
            <span>Hello Frank</span>
        </div>
    </message>
    <message sender="Frank" time="2016-02-03T22:58:39+01:00">
        <div>
            <span>Hi there Karen</span>
        </div>
        <div>
            <span>I'm back from New York</span>
        </div>
    </message>
    <message sender="Karen" time="2016-02-03T22:58:56+01:00">
        <div>
            <span>How are you doing?</span>
            <span>Everything OK?</span>
        </div>
    </message>
</chat>'''

ns={'msg' : "http://test.org/net/1.3"}
xml = ET.fromstring(rawxml)

for msg in xml.findall("msg:message", ns):
    print("Sender: " + msg.get("sender"))
    print("Time: " + msg.get("time"))
    body=""
    for d in msg.findall("msg:div", ns):
        body = body + ET.tostring(d, encoding="unicode")
    print("Content: " + body)

注意tostring()encoding="unicode"參數的使用,這使它返回一個字符串。 添加XML名稱空間屬性就是ElementTree與它們一起工作的方式。

暫無
暫無

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

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