Извлечение комментариев из файла XML в Python - PullRequest
0 голосов
/ 02 марта 2020

Я хотел бы извлечь раздел комментариев файла XML. Информация, которую я хотел бы извлечь, находится между тегом , а затем внутри тега Text , который является «ПРИМЕР».

Структура файла XML выглядит ниже.

<Boxes>

  <Box Id="3" ZIndex="13">
      <Shape>Rectangle</Shape>
      <Brush Id="0" />
      <Pen>
        <Color>#FF000000</Color>

      </Pen>
      <Tag>&lt;?xml version="1.0"?&gt;
&lt;PFDComment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  &lt;Text&gt;**EXAMPLE** &lt;/Text&gt;

&lt;/PFDComment&gt;</Tag>
  </Box>

</Boxes>

Я попробовал что-то ниже, но не смог получить нужную информацию.

def read_cooments(xml):
    tree = lxml.etree.parse(xml)

    Comments= {}
    for comment in tree.xpath("//Boxes/Box"):
    #                                
        get_id = comment.attrib['Id']
        Comments[get_id] = []
        for group in comment.xpath(".//Tag"):
        #                        
            Comments[get_id].append(group.text)

    df_name1 = pd.DataFrame(dict([(k,pd.Series(v)) for k,v in Comments.items()]))  

Может кто-нибудь помочь извлечь комментарии из файла XML, показанного выше? Любая помощь приветствуется!

1 Ответ

1 голос
/ 02 марта 2020

Используйте приведенный ниже код:

def read_comments(xml):
    tree = etree.parse(xml)
    rows= []
    for box in tree.xpath('Box'):
        id = box.attrib['Id']
        tagTxt = box.findtext('Tag')
        if tagTxt is None:
            continue
        txtNode = etree.XML(tagTxt).find('Text')
        if txtNode is None:
            continue
        rows.append([id, txtNode.text.strip()])
    return pd.DataFrame(rows, columns=['id', 'Comment'])

Обратите внимание, что если вы создаете DataFrame внутри функции, она является локальной переменной этой функции и не видна снаружи. Лучший и более читаемый подход (как и я) состоит в том, что функция возвращает этот DataFrame.

Эта функция также содержит continue в 2 местах, чтобы предотвратить возможные "случаи ошибок", когда элемент Box не содержит тег child или Tag не содержит Text дочерний элемент.

Я также заметил, что нет необходимости заменять &lt; или &gt; на < или > моим собственным кодом, так как l xml выполняет его самостоятельно .

Редактировать

Мой тест выглядит следующим образом: Запуск импорта формы:

import pandas as pd
from lxml import etree

Я использовал файл, содержащий:

<Boxes>
  <Box Id="3" ZIndex="13">
    <Shape>Rectangle</Shape>
    <Brush Id="0" />
    <Pen>
      <Color>#FF000000</Color>
    </Pen>
    <Tag>&lt;?xml version="1.0"?&gt;
&lt;PFDComment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  &lt;Text&gt;**EXAMPLE** &lt;/Text&gt;
&lt;/PFDComment&gt;</Tag>
  </Box>
</Boxes>

Я вызвал вышеупомянутая функция:

df_name1 = read_comments('Boxes.xml')

и когда я напечатал df_name1 , я получил:

  id      Comment
0  3  **EXAMPLE**

Если что-то пойдет не так, используйте «расширенную» версию вышеуказанная функция с тестовыми распечатками:

def read_comments(xml):
    tree = etree.parse(xml)
    rows= []
    for box in tree.xpath('Box'):
        id = box.attrib['Id']
        tagTxt = box.findtext('Tag')
        if tagTxt is None:
            print('No Tag element')
            continue
        txtNode = etree.XML(tagTxt).find('Text')
        if txtNode is None:
            print('No Text element')
            continue
        txt = txtNode.text.strip()
        print(f'{id}: {txt}')
        rows.append([id, txt])
    return pd.DataFrame(rows, columns=['id', 'Comment'])

и посмотрите на распечатки.

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