【问题标题】:Getting XML into a SQLite3 database using Python 3使用 Python 3 将 XML 导入 SQLite3 数据库
【发布时间】:2018-09-20 20:57:32
【问题描述】:

我一直在尝试使用 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 标签内的内容,不包括封闭的消息标签,现在重命名为 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 数据放入表中?

【问题讨论】:

  • 你说的去掉b是什么意思?将字节串解码成普通的python字符串?
  • 好吧,也许我误解了一些事情。该字符串以b' 开头并以' 结尾。当我将它放入数据库时​​,我看不到它的用途。它是数据库 AFAIK 中的纯文本。
  • 是的,你不理解一些东西。我会给出一些解释的答案。

标签: python-3.x sqlite xml-parsing


【解决方案1】:

因此,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 works 使用它们的方式。

【讨论】:

  • 谢谢!很好的答案!
猜你喜欢
  • 2011-02-22
  • 2019-07-13
  • 2018-12-02
  • 2011-06-10
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多