Структура файла XML не позволяет мне читать его с помощью Python - PullRequest
1 голос
/ 09 мая 2019

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

Все работает так, как я хочу, однако при чтении из файла XML возникает ошибка из-за содержимого самого файла XML.

У меня есть скрипт для работы, редактирующий файл xml, но это не решение для меня, так как мне нужен этот скрипт для запуска тысяч файлов

вот код, который я использую:

import os
import tkinter as tk
from tkinter import filedialog
import xml.etree.ElementTree as ET


root = tk.Tk()
root.withdraw()

file_path = filedialog.askopenfilenames()

tup=0

count = len(file_path)

for i in range(len(file_path)):
    filename = os.path.basename(file_path[tup])
    print('file =',os.path.basename(' '.join(file_path)))
    tree = ET.parse(file_path[tup])
    root = tree.getroot()
    for child in root:
        data = child.tag
        print(data)
    for data in root.findall(data):
        name = data.find('subdata2').text
        print('ID =', name)
    tup +=1

и вот пример xml:

<?xml version="1.0"?>
<Data xmlns="link">
    <subdata1 id = "something">
        <subdata2>data
            <subdata3>data</subdata3>
        </subdata2>
    </subdata1>
</Data>

Проблема возникает из текста, прикрепленного к корню "link3" он изменяет тег subdata1 с

subdata1

до

 {link}subdata1

и это затем меняет вывод с:

ID = data

до:

Traceback (most recent call last):
  File "debug.py", line 25, in <module>
    name = data.find('subdata2').text
AttributeError: 'NoneType' object has no attribute 'text'

Есть ли другой способ извлечения данных из этого XML-файла, который не включает изменение самого XML-файла?

1 Ответ

0 голосов
/ 10 мая 2019

Вы можете удалить пространства имен из проанализированного xml вместо самого xml.

tree = ET.iterparse(file_path)
for _, el in tree:
    if '}' in el.tag:
        el.tag = el.tag.split('}', 1)[1]  # strip all namespaces
root = tree.root
for child in root:
    # ... (REST OF CODE)

Подробнее здесь


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

import untangle

root = untangle.parse(file_path)
print(root.Data.subdata1['id'])
print(root.Data.subdata1.subdata2.cdata)

Я также забыл свой любимый вариант. xmltodict преобразует xml в объекты Python OrderedDict.

import xmltodict

with open(xmlPath, 'rb') as fd:
    xmlDict = xmltodict.parse(fd)
print(xmlDict['Data']['subdata1']['@id'])
print(xmlDict['Data']['subdata1']['subdata2']['#text'])

Как видите, пространства имен не будут проблемой. А если вы знакомы с диктовками Python, то вам будет очень просто выполнить итерацию и найти то, что вы хотите.

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