Как я могу проанализировать приведенные ниже данные XML, используя Python? - PullRequest
0 голосов
/ 21 января 2020

Источник XML

<?xml version='1.0' encoding='UTF-8'?>
<ProcessType xmlns:xmi="http://www.omg.org/XMI" xmi:version="2.0" defaultContext="Default">
    <node componentName="tRedshiftRow" componentVersion="0.102" offsetLabelX="0" offsetLabelY="0" posX="-32" posY="96">
    <elementParameter field="TECHNICAL" name="QUERYSTORE:QUERYSTORE_TYPE" value="BUILT_IN"/>
    <elementParameter field="TEXT" name="DBNAME" value="&quot;&quot;"/>
    <elementParameter field="TEXT" name="SCHEMA_DB" value="&quot;&quot;"/>
    <elementParameter field="MEMO_SQL" name="QUERY" value="&quot;DELETE FROM schema.tablename;&quot;"/>
    </node>
</ProcessType>

Я хочу получить оператор DELETE только для тега "QUERY" и записать его в текстовый файл.

Ожидаемый вывод: DELETE FROM schema.tablename;

Я пробовал следующий способ, который, очевидно, не сработал!

from lxml import etree, objectify
import xml.etree.ElementTree as ET

def convert_xml_to_comp():
    metadata = 'source.xml'
    parser = etree.XMLParser(remove_blank_text=True)
    tree = etree.parse(metadata, parser)
    root = tree.getroot()
    for elem in root.getiterator():
        # print(elem)
        i = elem.tag.find('}')
        if i >= 0:
            elem.tag = elem.tag[i+1 :]
    objectify.deannotate(root, cleanup_namespaces=True)
    tree.write('done.xml', pretty_print=True, xml_declaration=True, encoding='UTF-8')


tree = ET.parse('done.xml')
root = tree.getroot()

def get_sql_text():

    file = open( "newdelete.txt", "w")
    for root in tree.getroot():
        ### Get the elements' names ###
        for elementParameter in root.iterfind('elementParameter[@name="UNIQUE_NAME"]') :
                        name=elementParameter.get('value')
                        ### Get the elements' name and SQL ###
                        for elementParameter in root.iterfind('elementParameter[@name="QUERY"]') :
                            #print (root.attrib)
                            val=elementParameter.get('value')
                            print(root.find('val[@value="DELETE FROM schema.tablename;"]'))
    file.close() 
get_sql_text()
if __name__ == '__main__':
    convert_xml_to_comp()

1 Ответ

4 голосов
/ 21 января 2020

Вы делаете это всего за пару операторов, используя запрос xpath. Что-то вроде:

>>> from lxml import etree
>>> doc = etree.parse(open('data.xml'))
>>> query = doc.xpath('//elementParameter[@name="QUERY"]')[0].get('value')
>>> print(query)
"DELETE FROM schema.tablename;"

Это говорит "найти все элементы elementParameter с name="QUERY" и затем вернуть значение атрибута value первого.


Чтобы выбрать только те элементы, которые содержат «DELETE» в атрибуте value, используйте функцию contains():

>>> doc.xpath('//elementParameter[@name="QUERY" and contains(@value, "DELETE")]')
...