Python xmltodict - PullRequest
       19

Python xmltodict

0 голосов
/ 10 ноября 2018

Я пытаюсь прочитать файл XML, чтобы обновить версию программного обеспечения. В частности, файл XML содержит набор инкрементных обновлений, для которых могут потребоваться обновления базы данных в виде запросов SQL. Проблема в том, что я недостаточно знаком с чтением файлов XML, чтобы выяснить, как заставить это работать должным образом. Ниже приведен пример файла XML и кода Python (2.7), который я использую, чтобы попытаться прочитать его.

По сути, код python будет проверять версию @release и, если она больше, чем существующая версия программного обеспечения / базы данных, запустить код SQL. (Я могу легко добавить код для выполнения запроса, когда узнаю, как получить строку SQL в переменную.)

Кто-нибудь может дать мне несколько советов, где я могу ошибаться?

<?xml version="1.0"?>
<UNITNAME>
    <!--Version Release-->
    <databaseversion>1.0</databaseversion>
    <softwareversion>2.0</softwareversion>
    <released>2018-11-07</released>
    <!--Database Upgrade Queries-->
    <Database>
        <version release="1.0">
            <sql>UPDATE `system_defaults` SET `default_value`=1.0 WHERE `default_name`='DATABASEVERSION';</sql>
            <sql>UPDATE `system_defaults` SET `default_value`=1.0 WHERE `default_name`='SOFTWAREVERSION';</sql>
        </version>
        <version release="2.0">
            <sql>UPDATE `system_defaults` SET `default_value`=2.0 WHERE `default_name`='DATABASEVERSION';</sql>
            <sql>UPDATE `system_defaults` SET `default_value`=2.0 WHERE `default_name`='SOFTWAREVERSION';</sql>
        </version>
    </Database>
</UNITNAME>

И код Python: переменная 'f', конечно, является местоположением файла urlopen в интернете (и он отлично загружается).

            data=f.read()
            f.close()
            data=xmltodict.parse(data)
            if isinstance(data, dict):
                for k0, v0 in data["EM83D"]["Database"].iteritems():
                    #print k0, v0
                    if isinstance(v0, (list, dict)):
                        #print v0
                        for k1, v1 in v0.iteritems():
                            #print k1, v1
                            if isinstance(v1, (list, dict)):
                                print v1
                                for k2, v2 in v1.iteritems():
                                    print k2, v2['#text']

1 Ответ

0 голосов
/ 10 ноября 2018

Вы должны использовать BeautifulSoup для этой задачи, вот пример того, как получить атрибут «release» из кода xml;

from bs4 import BeautifulSoup as bs

xml = '''<?xml version="1.0"?>
<UNITNAME>
    <!--Version Release-->
    <databaseversion>1.0</databaseversion>
    <softwareversion>2.0</softwareversion>
    <released>2018-11-07</released>
    <!--Database Upgrade Queries-->
    <Database>
        <version release="1.0">
            <sql>UPDATE `system_defaults` SET `default_value`=1.0 WHERE `default_name`='DATABASEVERSION';</sql>
            <sql>UPDATE `system_defaults` SET `default_value`=1.0 WHERE `default_name`='SOFTWAREVERSION';</sql>
        </version>
        <version release="2.0">
            <sql>UPDATE `system_defaults` SET `default_value`=2.0 WHERE `default_name`='DATABASEVERSION';</sql>
            <sql>UPDATE `system_defaults` SET `default_value`=2.0 WHERE `default_name`='SOFTWAREVERSION';</sql>
        </version>
    </Database>
</UNITNAME>'''

soup = bs(xml, 'html.parser') # or replace 'html.parser' with 'lxml' if installed (its much faster)

database_version = soup.find('databaseversion').text
software_version = soup.find('softwareversion').text

if float(software_version) > float(database_version):
    sql_statements = soup.find('version', attrs={'release': float(software_version)})
    for query in sql_statements.find_all('sql'):
        print(query.text)
else:
    print('The database does not need to be updated.')

Таким образом, если версия программного обеспечения больше, чем версия базы данных, этот код будет напечатан;

UPDATE `system_defaults` SET `default_value`=2.0 WHERE `default_name`='DATABASEVERSION';
UPDATE `system_defaults` SET `default_value`=2.0 WHERE `default_name`='SOFTWAREVERSION';
...