Получение XML в базу данных SQLite3 с использованием Python 3 - PullRequest
0 голосов
/ 20 сентября 2018

Я пытался получить данные из указанного XML-файла в базу данных SQLite3 с помощью ElementTree.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 в таблицу без всех этих escape-символов?

1 Ответ

0 голосов
/ 21 сентября 2018

Итак, 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)

Обратите внимание на использование аргумента encoding="unicode" для tostring(), что заставляет его возвращать строку.Добавление атрибутов пространства имен XML - это то, как ElementTree работает с ними .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...