Чтение XML-файла с использованием дерева элементов

1

У меня есть один xml файл. Похоже,

<root>
  <Group>    
    <ChapterNo>1</ChapterNo>    
    <ChapterName>A</ChapterName>    
    <Line>1</Line>    
    <Content>zfsdfsdf</Content>    
    <Synonyms>fdgd</Synonyms>    
    <Translation>assdfsdfsdf</Translation>    
  </Group>    
  <Group>    
    <ChapterNo>1</ChapterNo>    
    <ChapterName>A</ChapterName>    
    <Line>2</Line>    
    <Content>ertreter</Content>    
    <Synonyms>retreter</Synonyms>    
    <Translation>erterte</Translation>    
  </Group>    
  <Group>    
    <ChapterNo>2</ChapterNo>    
    <ChapterName>B</ChapterName>    
    <Line>1</Line>    
    <Content>sadsafs</Content>
    <Synonyms>sdfsdfsd</Synonyms>
    <Translation>sdfsdfsd</Translation>
  </Group>
  <Group>
    <ChapterNo>2</ChapterNo>
    <ChapterName>B</ChapterName>
    <Line>2</Line>
    <Content>retete</Content>
    <Synonyms>retertret</Synonyms>
    <Translation>retertert</Translation>
  </Group>
</root>

Я пробовал таким образом.......

root = ElementTree.parse('data.xml').getroot()
ChapterNo = root.find('ChapterNo').text 
ChapterName = root.find('ChapterName').text 
GitaLine = root.find('Line').text 
Content = root.find('Content').text 
Synonyms = root.find('Synonyms').text 
Translation = root.find('Translation').text

Но он показывает ошибку

ChapterNo=root.find('ChapterNo').text 
AttributeError: 'NoneType' object has no attribute 'text'`

Теперь я хочу, чтобы все ChapterNo, ChapterName и т.д. отдельно использовали дерево элементов, и я хочу вставить эти dats в базу данных... Кто-нибудь может мне помочь?

Rgds,

Nimmy

  • 0
    я попытался ......... root = ElementTree.parse ('data.xml'). getroot () ChapterNo = root.find ('ChapterNo'). text ChapterName = root.find ('ChapterName'). text GitaLine = root.find ('Line'). text Content = root.find ('Content'). text Синонимы = root.find ('Synonyms'). text Translation = root.find ('Translation'). text Но это показывает ошибку "ChapterNo = root.find ('ChapterNo'). text AttributeError: у объекта 'NoneType' нет атрибута 'text'"
  • 0
    Добавьте это в свой вопрос, его трудно прочитать в комментарии.
Показать ещё 1 комментарий
Теги:
elementtree

3 ответа

2

Чтобы проанализировать вашу простую двухуровневую структуру данных и собрать dict для каждой группы, все, что вам нужно сделать, это следующее:

>>> # what you did to get `root`
>>> from pprint import pprint as pp
>>> for group in root:
...     d = {}
...     for elem in group:
...         d[elem.tag] = elem.text
...     pp(d) # or whack it ito a database
...
{'ChapterName': 'A',
 'ChapterNo': '1',
 'Content': 'zfsdfsdf',
 'Line': '1',
 'Synonyms': 'fdgd',
 'Translation': 'assdfsdfsdf'}
{'ChapterName': 'A',
 'ChapterNo': '1',
 'Content': 'ertreter',
 'Line': '2',
 'Synonyms': 'retreter',
 'Translation': 'erterte'}
{'ChapterName': 'B',
 'ChapterNo': '2',
 'Content': 'sadsafs',
 'Line': '1',
 'Synonyms': 'sdfsdfsd',
 'Translation': 'sdfsdfsd'}
{'ChapterName': 'B',
 'ChapterNo': '2',
 'Content': 'retete',
 'Line': '2',
 'Synonyms': 'retertret',
 'Translation': 'retertert'}
>>>

Посмотри, Ма, не хат!

1

ChapterNo не является прямым дочерним элементом root, поэтому root.find('ChapterNo') не будет работать. Вам нужно будет использовать синтаксис xpath для поиска данных.

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

chapter_nos = [e.text for e in root.findall('.//ChapterNo')]

и т.д.

  • 2
    Обратите внимание, что в большом XML-документе /root/Group/ChapterNo будет быстрее, чем //ChapterNo .
0

Вот небольшой пример, используя sqlalchemy, чтобы определить объект, который будет извлекать и хранить данные в sqlite.

from sqlalchemy import create_engine, Unicode, Integer, Column, UnicodeText
from sqlalchemy.orm import create_session
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///chapters.sqlite', echo=True)
Base = declarative_base(bind=engine)

class ChapterLine(Base):
    __tablename__ = 'chapterlines'
    chapter_no = Column(Integer, primary_key=True)
    chapter_name = Column(Unicode(200))
    line = Column(Integer, primary_key=True)
    content = Column(UnicodeText)
    synonyms = Column(UnicodeText)
    translation = Column(UnicodeText)

    @classmethod
    def from_xmlgroup(cls, element):
        l = cls()
        l.chapter_no = int(element.find('ChapterNo').text)
        l.chapter_name = element.find('ChapterName').text
        l.line = int(element.find('Line').text)
        l.content = element.find('Content').text
        l.synonyms = element.find('Synonyms').text
        l.translation = element.find('Translation').text
        return l

Base.metadata.create_all() # creates the table

Здесь, как его использовать:

from xml.etree import ElementTree as etree

session = create_session(bind=engine, autocommit=False)
doc = etree.parse('myfile.xml').getroot()
for group in doc.findall('Group'):
    l = ChapterLine.from_xmlgroup(group)
    session.add(l)

session.commit()

Я тестировал этот код в ваших xml-данных, и он отлично работает, вставляя все в базу данных.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню