2015-03-31 2 views
0

У меня есть файл XML с приличным размером, который я извлекаю из API monit, используя следующий код в Python.XML vs Словарь в python для поиска и извлечения

file = urllib.request.urlopen(URL) #opening the XML URL 
    data = file.read() 
    file.close() 
    list.append(parsedXML, xmltodict.parse(data)) #Parsing to dict the XML file created 

Я использую XMLtoDICT для преобразования XML в словарь, так как я полагал, что было бы легче искать и извлекать из. XMLtoDICT создает вложенный, упорядоченный словарь, что отлично. Однако я не вижу простого способа поиска каждого «слоя» питона python и извлечения всего узла.

Есть ли простой способ поиска и вывода узла словаря в python для редактирования?

Например, посмотрите на XML ниже. Как только он находится в словаре, мне нужно вытащить каждый узел, начинающийся с «<service» (в полном XML-файле будет много) и запустить тесты на этом точном узле и, возможно, изменить значения.
Мне также нужно будет найти все значения в словаре, найти значение, затем получить имя родительского узла этого значения и извлечь весь узел. Это возможно?

Или, должен ли я просто полностью пропустить словарь и использовать XML напрямую? Если да, существует ли библиотека python для XML, которая поддерживает все эти функции?

Вот пример данных XML я тянущие: алгоритм обхода

<monit> 
    <server> 
     <id>9d8b2a3d3618ccc38628f6d7b89ebfd8</id> 
     <incarnation>1427714713</incarnation> 
     <version>5.4</version> 
     <uptime>44395</uptime> 
     <poll>120</poll> 
     <startdelay>0</startdelay> 
     <localhostname>DMZ-Server</localhostname> 
     <controlfile>/etc/monit/monitrc</controlfile> 
     <httpd> 
      <address>192.168.1.100</address> 
      <port>2812</port> 
      <ssl>0</ssl> 
     </httpd> 
    </server> 
    <platform> 
     <name>Linux</name> 
     <release>2.6.32-34-pve</release> 
     <version>#1 SMP Sat Nov 8 09:38:26 CET 2014</version> 
     <machine>i686</machine> 
     <cpu>8</cpu> 
     <memory>3145728</memory> 
     <swap>1048576</swap> 
    </platform> 
    <service type="3"> 
     <name>mmonit</name> 
     <collected_sec>1427759050</collected_sec> 
     <collected_usec>180381</collected_usec> 
     <status>0</status> 
     <status_hint>0</status_hint> 
     <monitor>1</monitor> 
     <monitormode>0</monitormode> 
     <pendingaction>0</pendingaction> 
     <pid>11481</pid> 
     <ppid>1</ppid> 
     <uptime>692522</uptime> 
     <children>0</children> 

ответ

0

Любого дерева будет делать трюк.

http://rosettacode.org/wiki/Tree_traversal#Python

Я хотел бы придерживаться с XML и использовать LXML для анализа и обхода дерева XML.

http://lxml.de/tutorial.html
http://lxml.de/tutorial.html#the-elementtree-class

Я уверен, что другие здесь будут предложены новые библиотеки XML, не стесняйтесь использовать их. LXML - единственный, с которым я знаком.

+0

Удивительно, я сохраню файл в XML и использую LXML, у него, кажется, есть все, что мне нужно. – deranjer

0

Для поиска и извлечения я бы предложил пропустить словарь и просто работать с XML «напрямую». XPath - это концепция, которая оказалась мощной для прохождения и получения определенной части документа XML. Например, чтобы получить <service> элемент в любом месте документа XML, вы можете просто сказать, в XPath: //service

LXML как уже упоминалось в другом ответе, это один из возможных вариантов библиотеки в Python, что support XPath. Например:

from lxml import etree 
xml_source = """<root> 
    <server> 
     <id>9d8b2a3d3618ccc38628f6d7b89ebfd8</id> 
     <incarnation>1427714713</incarnation> 
     <version>5.4</version> 
     <uptime>44395</uptime> 
     <poll>120</poll> 
     <startdelay>0</startdelay> 
     <localhostname>DMZ-Server</localhostname> 
     <controlfile>/etc/monit/monitrc</controlfile> 
     <httpd> 
      <address>192.168.1.100</address> 
      <port>2812</port> 
      <ssl>0</ssl> 
     </httpd> 
    </server> 
    <platform> 
     <name>Linux</name> 
     <release>2.6.32-34-pve</release> 
     <version>#1 SMP Sat Nov 8 09:38:26 CET 2014</version> 
     <machine>i686</machine> 
     <cpu>8</cpu> 
     <memory>3145728</memory> 
     <swap>1048576</swap> 
    </platform> 
    <service type="3"> 
     <name>mmonit</name> 
     <collected_sec>1427759050</collected_sec> 
     <collected_usec>180381</collected_usec> 
     <status>0</status> 
     <status_hint>0</status_hint> 
     <monitor>1</monitor> 
     <monitormode>0</monitormode> 
     <pendingaction>0</pendingaction> 
     <pid>11481</pid> 
     <ppid>1</ppid> 
     <uptime>692522</uptime> 
     <children>0</children> 
    </service> 
</root>""" 

doc = etree.fromstring(xml_source) 
service = doc.find('.//service') 
#you can then operate on service as needed: 
#parse it to dictionary, or in this example print the markup 
print(etree.tostring(service, pretty_print=True)) 
Смежные вопросы