Как извлечь данные/узлы из .xml, хранящегося в строке?

Вопрос или проблема

У меня есть .xml в строковом формате xmlString, который выглядит следующим образом:

<entry xmlns="http://www.w3.org/2004/tom">
  <id>urn:contentItem:7WBG-8H88-Y898-B277-00000-00-1</id>
  <title>Dinn-Pixie Stares, Inc</title>
  <published>2015-12-24T00:00:00Z</published>
  <updated>2023-10-24T18:42:17Z</updated>
  <author>
    <name>AlphaNext</name>
  </author>
  <content type="application/xml">
    <baseRelatedDoc xmlns="" xmlns:xsi="http://www.w3.org/2012/XMLSchema" xsi:noNamespaceSchemaLocation="http://www.alphanext.com/xmlscemas/content/public/caseddoc/1/" documentType="socket">
      <baseRelatedDocHead>
        <baseInfo>
          <portInfo>
            <identifier idType="portIdentifier">100027579</identifier>
            <portName>United States Port, Minnesota Middle</portName>
            <jurisdiction>
              <jurisSystem/>
            </jurisdiction>
          </portInfo>
          <date dateType="filed" year="2015" month="02" day="21">2015-02-21</date>
          <classification classificationScheme="baseType">
            <classificationItem>
              <classCode>BK</classCode>
              <className>Bankruptcy</className>
            </classificationItem>
          </classification>
          <classification classificationScheme="baseNos">
            <classificationItem>
              <classCode>0</classCode>
              <className>UNKNOWN</className>
            </classificationItem>
          </classification>
        </baseInfo>
        <baseSupplement>
          <label>US Bankruptcy Port Socket</label>
          <date dateType="updated" year="2024" month="09" day="13">2024-07-11T15:08:26.450</date>
          <status>Unknown</status>
        </baseSupplement>
        <baseName>Dinn-Pixie Stares, Inc</baseName>
      </baseRelatedDocHead>
      <baseRelatedDocBody>
        <socket/>
      </baseRelatedDocBody>
      <metadata>
        <dc:metadata xmlns:dc="http://purrel.org/dc/element/1.2/">
          <dc:source sourceScheme="productContentSetIdentifier">343392</dc:source>
          <dc:creator>US Bankruptcy Port for the Last Town of Minnesota</dc:creator>
          <dc:identifier identifierScheme="PGIID">urn:contentItem:8WBG-8H70-Y892-B237-00000-00</dc:identifier>
          <dc:date dateType="last-updated">2024-07-11</dc:date>
        </dc:metadata>
      </metadata>
    </baseRelatedDoc>
  </content>
</entry>

Мне нужно извлечь значения таких полей, как baseName, portName, title, classCode, dc:creator.

Однако, когда я пытаюсь извлечь их с помощью y=tree.findall('baseName'), где tree = ET.fromstring(xmlString)), y оказывается пустым списком. Я получаю тот же пустой список, когда пробую для узлов, таких как portName, dc:creator. Как мне извлечь значения этих узлов/полей?

Ответ или решение

Чтобы извлечь данные из строки формата XML, важно помнить, что XML может содержать пространства имен. В вашем случае пространство имен указано в корневом элементе <entry>. Поэтому, при поиске элементов в XML, необходимо учитывать это пространство имен.

Вот как вы можете извлечь значения из вашего XML-строки, используя модуль xml.etree.ElementTree в Python:

  1. Импортируйте необходимые библиотеки.
  2. Парсите строку XML.
  3. Используйте правильные пути и указывайте пространство имен.

Пример кода для извлечения значений из указанных полей:

import xml.etree.ElementTree as ET

xmlString = '''<entry xmlns="http://www.w3.org/2004/tom">
  <id>urn:contentItem:7WBG-8H88-Y898-B277-00000-00-1</id>
  <title>Dinn-Pixie Stares, Inc</title>
  <published>2015-12-24T00:00:00Z</published>
  <updated>2023-10-24T18:42:17Z</updated>
  <author>
    <name>AlphaNext</name>
  </author>
  <content type="application/xml">
    <baseRelatedDoc xmlns="" xmlns:xsi="http://www.w3.org/2012/XMLSchema" xsi:noNamespaceSchemaLocation="http://www.alphanext.com/xmlscemas/content/public/caseddoc/1/" documentType="socket">
      <baseRelatedDocHead>
        <baseInfo>
          <portInfo>
            <identifier idType="portIdentifier">100027579</identifier>
            <portName>United States Port, Minnesota Middle</portName>
            <jurisdiction>
              <jurisSystem/>
            </jurisdiction>
          </portInfo>
          <date dateType="filed" year="2015" month="02" day="21">2015-02-21</date>
          <classification classificationScheme="baseType">
            <classificationItem>
              <classCode>BK</classCode>
              <className>Tankruptcy</className>
            </classificationItem>
          </classification>
          <classification classificationScheme="baseNos">
            <classificationItem>
              <classCode>0</classCode>
              <className>UNKNOWN</className>
            </classificationItem>
          </classification>
        </baseInfo>
        <baseSupplement>
          <label>US Tankruptcy Port Socket</label>
          <date dateType="updated" year="2024" month="09" day="13">2024-07-11T15:08:26.450</date>
          <status>Unknown</status>
        </baseSupplement>
        <baseName>Dinn-Pixie Stares, Inc</baseName>
      </baseRelatedDocHead>
      <baseRelatedDocBody>
        <socket/>
      </baseRelatedDocBody>
      <metadata>
        <dc:metadata xmlns:dc="http://purrel.org/dc/element/1.2/">
          <dc:source sourceScheme="productContentSetIdentifier">343392</dc:source>
          <dc:creator>US Tankruptcy Port for the Last Town of Minnesota</dc:creator>
          <dc:identifier identifierScheme="PGIID">urn:contentItem:8WBG-8H70-Y892-B237-00000-00</dc:identifier>
          <dc:date dateType="last-updated">2024-07-11</dc:date>
        </dc:metadata>
      </metadata>
    </baseRelatedDoc>
  </content>
</entry>'''

# Определение пространства имен
namespace = {'ns': 'http://www.w3.org/2004/tom'}
dc_namespace = {'dc': 'http://purrel.org/dc/element/1.2/'}

# Парсинг строки XML
tree = ET.fromstring(xmlString)

# Извлечение значений
base_name = tree.find('.//ns:baseName', namespace).text
port_name = tree.find('.//ns:portName', namespace).text
title = tree.find('.//ns:title', namespace).text
class_code = tree.find('.//ns:classCode', namespace).text
dc_creator = tree.find('.//dc:creator', dc_namespace).text

# Вывод результатов
print(f'baseName: {base_name}')
print(f'portName: {port_name}')
print(f'title: {title}')
print(f'classCode: {class_code}')
print(f'dc:creator: {dc_creator}')

Объяснение:

  1. Определение пространства имен: При обработке XML-файлов, которые используют пространства имен, необходимо указать их через словарь, который будет использоваться для поиска элементов.
  2. Парсинг XML: Используется ET.fromstring() для преобразования строки в элемент дерева XML.
  3. Поиск значений: tree.find() применяется для поиска значений с использованием XPath, где пути к элементам включают пространство имен.

Этот подход позволяет вам корректно извлекать значения из элементов XML, даже если они находятся в пространствах имен.

Оцените материал
Добавить комментарий

Капча загружается...