Как получить все дочерние узлы xml с помощью python?

Вступление

Данные являются наиболее важным ингредиентом в программировании. Это происходит во всех формах и формах. Иногда он расположен внутри документов, таких как CSV или JSON, но иногда он хранится в Интернете или в базах данных. Некоторые из него хранятся/передаются или обрабатываются через формат XML, который во многом способах аналогичен формату HTML, но его цель – передавать и хранить данные, в отличие от HTML, основной целью которого является отображение данных. Кроме того, способ написания HTML и XML похож на. Несмотря на различия и сходства, они очень хорошо дополняют друг друга.

Как XPath, так и XML разработаны одной и той же компанией W3C, которая налагает, что XPath – это самый совместимый модуль Python, который будет использоваться для анализа документов XML. Поскольку один из программных директоров, которые выдвинут вас к успеху программирования, заключается в том, чтобы «не изобретать колесо», мы собираемся обратиться к документу консорциума W3C ( https://www.w3.org/ ) и Источники в отношении синтаксиса и операторов на наших примерах, чтобы принести концепцию XPath ближе к людям, желающим понять его лучше и использовать его в реальных проблемах.

ИТ-индустрия приняла XML-способ передачи данных в качестве одного из его принципов. Представьте, что одна из ваших задач было собрать информацию из Интернета? Копирование и вставка являются одним из простейших инструментов для использования (так как он регулярно используется программистами); Это может привести нас только для того, чтобы собрать несколько простых данных из Интернета, хотя процесс может быть болезненно повторяется. И все же, в случае, если у нас будет более надежные данные, или больше веб-страниц, чтобы собрать данные, мы можем быть склонны использовать более продвинутые пакеты Python, чтобы автоматизировать наши данные сбора данных.

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

Для целей уборки веб-данных мы будем использовать несколько библиотек Python, которые позволяют нам делать только что. Первый из них – это модуль запросов. Что это делает, так это то, что он отправляет HTTP-запросы, что возвращает нам объект ответа. Он использовал только в том случае, если желание соскрести контент из Интернета. Если мы попытаемся анализировать статический файл XML, это не нужно.

Есть много разборных модулей. LXML, STRAPY и BUILYSOUP – это некоторые из них. Сказать, какой из них лучше, часто пренебрегают, поскольку их размер и функциональность отличается друг от друга. Например, BeautifulSoup является более сложной и обслуживает вас с большим количеством функциональности, но LXML и Scrapy наступают легкий и могут помочь вам пройти через документы, используя селекторы XPath и CSS.

Есть определенные подводные камни при попытке проехать через документ, используя XPath. Общая ошибка При попытке анализировать XML с помощью XPath Notiator, состоит в том, что многие люди пытаются использовать библиотеку BeautifulSoup. На самом деле это невозможно, так как он не содержит методов прохода XPath. Для тех целей мы будем использовать библиотеку LXML.

Библиотека запросов используется в том случае, если мы хотим загрузить HTML-маркируйте с конкретного веб-сайта.

Первый шаг будет установить необходимые пакеты. Через нотация Установка PIP Все вышеперечисленные модули могут быть достаточно легко установлены.

Необходимые шаги:

  1. (XPath модуль является частью LXML-библиотеки)
  2. (В случае, если контент на веб-странице)

Лучший способ объяснить анализ XML – это изображение по этому поводу.

Первый шаг будет установить необходимые модули. Кормушка PIP Установка нотации Все модули выше могут быть установлены довольно легко.

Namespace support

By default, does no XML namespace processing (it just treats namespace declarations as regular node attributes), but passing will make it expand namespaces for you:

>>> xml = """
... <root xmlns="http://defaultns.com/"
...       xmlns:a="http://a.com/"
...       xmlns:b="http://b.com/">
...   <x>1</x>
...   <a:y>2</a:y>
...   <b:z>3</b:z>
... </root>
... """
>>> xmltodict.parse(xml, process_namespaces=True) == {
...     'http://defaultns.com/:root': {
...         'http://defaultns.com/:x': '1',
...         'http://a.com/:y': '2',
...         'http://b.com/:z': '3',
...     }
... }
True

It also lets you collapse certain namespaces to shorthand prefixes, or skip them altogether:

>>> namespaces = {
...     'http://defaultns.com/': None, # skip this namespace
...     'http://a.com/': 'ns_a', # collapse "http://a.com/" -> "ns_a"
... }
>>> xmltodict.parse(xml, process_namespaces=True, namespaces=namespaces) == {
...     'root': {
...         'x': '1',
...         'ns_a:y': '2',
...         'http://b.com/:z': '3',
...     },
... }
True

Incremental parsing

lxml.etree provides two ways for incremental step-by-step parsing. One is
through file-like objects, where it calls the read() method repeatedly.
This is best used where the data arrives from a source like urllib or any
other file-like object that can provide data on request. Note that the parser
will block and wait until data becomes available in this case:

>>> class DataSource
...     data =  b"<roo", b"t><", b"a/", b"><", b"/root>" 
...     def read(self, requested_size):
...         try
...             return self.data.pop()
...         except IndexError
...             return b''

>>> tree = etree.parse(DataSource())

>>> etree.tostring(tree)
b'<root><a/></root>'

The second way is through a feed parser interface, given by the feed(data)
and close() methods:

>>> parser = etree.XMLParser()

>>> parser.feed("<roo")
>>> parser.feed("t><")
>>> parser.feed("a/")
>>> parser.feed("><")
>>> parser.feed("/root>")

>>> root = parser.close()

>>> etree.tostring(root)
b'<root><a/></root>'

Here, you can interrupt the parsing process at any time and continue it later
on with another call to the feed() method. This comes in handy if you
want to avoid blocking calls to the parser, e.g. in frameworks like Twisted,
or whenever data comes in slowly or in chunks and you want to do other things
while waiting for the next chunk.

After calling the close() method (or when an exception was raised
by the parser), you can reuse the parser by calling its feed()
method again:

Elements contain text

Elements can contain text:

>>> root = etree.Element("root")
>>> root.text = "TEXT"

>>> print(root.text)
TEXT

>>> etree.tostring(root)
b'<root>TEXT</root>'

In many XML documents (data-centric documents), this is the only place where
text can be found. It is encapsulated by a leaf tag at the very bottom of the
tree hierarchy.

However, if XML is used for tagged text documents such as (X)HTML, text can
also appear between different elements, right in the middle of the tree:

<html><body>Hello<br/>World</body></html>

Here, the <br/> tag is surrounded by text. This is often referred to as
document-style or mixed-content XML. Elements support this through their
tail property. It contains the text that directly follows the element, up
to the next element in the XML tree:

>>> html = etree.Element("html")
>>> body = etree.SubElement(html, "body")
>>> body.text = "TEXT"

>>> etree.tostring(html)
b'<html><body>TEXT</body></html>'

>>> br = etree.SubElement(body, "br")
>>> etree.tostring(html)
b'<html><body>TEXT<br/></body></html>'

>>> br.tail = "TAIL"
>>> etree.tostring(html)
b'<html><body>TEXT<br/>TAIL</body></html>'

The two properties .text and .tail are enough to represent any
text content in an XML document. This way, the ElementTree API does
not require any in addition to the Element
class, that tend to get in the way fairly often (as you might know
from classic DOM APIs).

However, there are cases where the tail text also gets in the way.
For example, when you serialise an Element from within the tree, you
do not always want its tail text in the result (although you would
still want the tail text of its children). For this purpose, the
tostring() function accepts the keyword argument with_tail:

>>> etree.tostring(br)
b'<br/>TAIL'
>>> etree.tostring(br, with_tail=False) # lxml.etree only!
b'<br/>'

If you want to read only the text, i.e. without any intermediate
tags, you have to recursively concatenate all text and tail
attributes in the correct order. Again, the tostring() function
comes to the rescue, this time using the method keyword:

Elements carry attributes as a dict

XML elements support attributes. You can create them directly in the Element
factory:

>>> root = etree.Element("root", interesting="totally")
>>> etree.tostring(root)
b'<root interesting="totally"/>'

Attributes are just unordered name-value pairs, so a very convenient way
of dealing with them is through the dictionary-like interface of Elements:

>>> print(root.get("interesting"))
totally

>>> print(root.get("hello"))
None
>>> root.set("hello", "Huhu")
>>> print(root.get("hello"))
Huhu

>>> etree.tostring(root)
b'<root interesting="totally" hello="Huhu"/>'

>>> sorted(root.keys())


>>> for name, value in sorted(root.items()):
...     print('%s = %r' % (name, value))
hello = 'Huhu'
interesting = 'totally'

For the cases where you want to do item lookup or have other reasons for
getting a ‘real’ dictionary-like object, e.g. for passing it around,
you can use the attrib property:

>>> attributes = root.attrib

>>> print(attributes"interesting"])
totally
>>> print(attributes.get("no-such-attribute"))
None

>>> attributes"hello" = "Guten Tag"
>>> print(attributes"hello"])
Guten Tag
>>> print(root.get("hello"))
Guten Tag

Note that attrib is a dict-like object backed by the Element itself.
This means that any changes to the Element are reflected in attrib
and vice versa. It also means that the XML tree stays alive in memory
as long as the attrib of one of its Elements is in use. To get an
independent snapshot of the attributes that does not depend on the XML
tree, copy it into a dict:

7.2. Конструктор Element()¶

Этот конструктор создает и возвращает новый экземпляр Element.

etree.Element(tag, attrib={}, nsmap=None, **extras)
tag
Строка, содержащая имя создаваемого элемента.
attrib
Словарь, содержащий имена и значения атрибутов, которые необходимо добавить в элемент. Значение по умолчанию — отсутствие атрибутов.
nsmap
Если ваш документ содержит несколько пространств имен XML, вы можете указать карту пространства имен, которая определяет префиксы пространства имен, которые вы хотели бы использовать, когда этот документ преобразуется в XML. См. Раздел 4.3 «Карты пространства имен».
extras
Любые аргументы в виде name = value, которое вы поставляете конструктору, добавляются к атрибутам элемента. Например, этот код:
newReed = etree.Element('reed', pitch='440', id='a4')

создаст элемент, который выглядит так:

<reed pitch='440' id='a4'/>

Ниже приведен пример создания документа с несколькими пространствами имен с использованием аргумента ключевого слова nsmap.

#!/usr/bin/env python
import sys
from lxml import etree as et

HTML_NS  =  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
XSL_NS   =  "http://www.w3.org/1999/XSL/Transform"
NS_MAP = {None  HTML_NS,
  "xsl" XSL_NS}

rootName = et.QName(XSL_NS, 'stylesheet')
root = et.Element(rootName, nsmap=NS_MAP)
sheet = et.ElementTree(root)

top = et.SubElement(root, et.QName(XSL_NS, "template"), match='/')
html = et.SubElement(top, et.QName(HTML_NS, "html"))
head = et.SubElement(html, "head")
title = et.SubElement(head, "title")
title.text = "Heading title"
body = et.SubElement(html, "body")
h1 = et.SubElement(body, "h1")
h1.text = "Body heading"
p = et.SubElement(body, "p")
p.text = "Paragraph text"
sheet.write(sys.stdout, pretty_print=True)

Когда этот корневой элемент сериализуется в XML, он будет выглядеть примерно так:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  <xsl:template match="/">
        <html>
                <head>
                        <title>Heading title</title>
                </head>
                <body>
                        <h1>Body heading</h1>
                        <p>Paragraph text</p>
                </body>
        </html>
  </xsl:template>
</xsl:stylesheet>

Существует одна незначительная патология этого конструктора. Если вы передадите предварительно построенный словарь в качестве аргумента атрибута, а также укажите аргументы ключевого слова, значения аргументов ключевого слова будут добавлены в этот словарь, как если бы вы использовали метод .update () в словаре атрибутов. Вот пример, показывающий этот побочный эффект:

Модификация XML

Ранее названия фильмов были в полном беспорядке. Теперь распечатайте их снова:

for movie in root.iter('movie'):    print(movie.attrib){'favorite': 'True', 'title': 'Indiana Jones: The raiders of the lost Ark'}{'favorite': 'True', 'title': 'THE KARATE KID'}{'favorite': 'False', 'title': 'Back 2 the Future'}{'favorite': 'False', 'title': 'X-Men'}{'favorite': 'True', 'title': 'Batman Returns'}{'favorite': 'False', 'title': 'Reservoir Dogs'}{'favorite': 'False', 'title': 'ALIEN'}{'favorite': 'True', 'title': "Ferris Bueller's Day Off"}{'favorite': 'FALSE', 'title': 'American Psycho'}{'favorite': 'False', 'title': 'Batman: The Movie'}{'favorite': 'True', 'title': 'Easy A'}{'favorite': 'True', 'title': 'Dinner for SCHMUCKS'}{'favorite': 'False', 'title': 'Ghostbusters'}{'favorite': 'True', 'title': 'Robin Hood: Prince of Thieves'}

Исправьте «2» в Back 2 the Future. Это должно быть проблемой поиска и замены. Напишите код, чтобы найти заголовок «Back 2 the Future» и сохраните его как переменную:

b2tf = root.find("./genre/decade/movie")print(b2tf)<Element 'movie' at 0x10ce00ef8>

Обратите внимание, что с помощьюметод возвращает элемент дерева В большинстве случаев более полезно редактировать контент внутри элемента. Изменитьатрибут переменной Back 2 the Future для чтения «Назад в будущее»

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

Изменитьатрибут переменной Back 2 the Future для чтения «Назад в будущее». Затем распечатайте атрибуты вашей переменной, чтобы увидеть ваши изменения. Вы можете легко сделать это, открыв атрибут элемента, а затем присвоив ему новое значение:

b2tf.attrib = "Back to the Future"print(b2tf.attrib){'favorite': 'False', 'title': 'Back to the Future'}

Запишите ваши изменения обратно в XML, чтобы они были постоянно зафиксированы в документе. Распечатайте атрибуты вашего фильма еще раз, чтобы убедиться, что ваши изменения работали. Использоватьспособ сделать это:

tree.write("movies.xml")tree = ET.parse('movies.xml')root = tree.getroot()for movie in root.iter('movie'):    print(movie.attrib){'favorite': 'True', 'title': 'Indiana Jones: The raiders of the lost Ark'}{'favorite': 'True', 'title': 'THE KARATE KID'}{'favorite': 'False', 'title': 'Back to the Future'}{'favorite': 'False', 'title': 'X-Men'}{'favorite': 'True', 'title': 'Batman Returns'}{'favorite': 'False', 'title': 'Reservoir Dogs'}{'favorite': 'False', 'title': 'ALIEN'}{'favorite': 'True', 'title': "Ferris Bueller's Day Off"}{'favorite': 'FALSE', 'title': 'American Psycho'}{'favorite': 'False', 'title': 'Batman: The Movie'}{'favorite': 'True', 'title': 'Easy A'}{'favorite': 'True', 'title': 'Dinner for SCHMUCKS'}{'favorite': 'False', 'title': 'Ghostbusters'}{'favorite': 'True', 'title': 'Robin Hood: Prince of Thieves'}

Serializing XML to a Stream¶

tostring() is implemented to write to an in-memory file-like
object and then return a string representing the entire element tree.
When working with large amounts of data, it will take less memory and
make more efficient use of the I/O libraries to write directly to a
file handle using the write() method of ElementTree.

import sys
from xml.etree.ElementTree import Element, SubElement, Comment, ElementTree

top = Element('top')

comment = Comment('Generated for PyMOTW')
top.append(comment)

child = SubElement(top, 'child')
child.text = 'This child contains text.'

child_with_tail = SubElement(top, 'child_with_tail')
child_with_tail.text = 'This child has regular text.'
child_with_tail.tail = 'And "tail" text.'

child_with_entity_ref = SubElement(top, 'child_with_entity_ref')
child_with_entity_ref.text = 'This & that'

empty_child = SubElement(top, 'empty_child')

ElementTree(top).write(sys.stdout)

The example uses to write to the
console, but it could also write to an open file or socket.

$ python ElementTree_write.py

<top><!--Generated for PyMOTW--><child>This child contains text.</ch
ild><child_with_tail>This child has regular text.</child_with_tail>A
nd "tail" text.<child_with_entity_ref>This &amp; that</child_with_en
tity_ref><empty_child /></top>

The last node in the tree contains no text or sub-nodes, so it is
written as an empty tag, <empty_child />. write() takes a
method argument to control the handling for empty nodes.

import sys
from xml.etree.ElementTree import Element, SubElement, ElementTree

top = Element('top')

child = SubElement(top, 'child')
child.text = 'This child contains text.'

empty_child = SubElement(top, 'empty_child')

for method in  'xml', 'html', 'text' ]:
    print method
    ElementTree(top).write(sys.stdout, method=method)
    print '\n'
    

Three methods are supported:

xml
The default method, produces <empty_child />.
html
Produce the tag pair, as is required in HTML documents
(<empty_child></empty_child>).
text
Prints only the text of nodes, and skips empty tags entirely.
$ python ElementTree_write_method.py

xml
<top><child>This child contains text.</child><empty_child /></top>

html
<top><child>This child contains text.</child><empty_child></empty_child></top>

text
This child contains text.

See also

Outline Processor Markup Language, OPML
Dave Winer’s OPML specification and documentation.

Удаление

Как и следовало ожидать, модуль ElementTree имеет необходимые функции для удаления атрибутов и подэлементов узла.

Удаление атрибута

В приведенном ниже коде показано, как удалить атрибут узла с помощью функции pop(). Функция применяется к параметру объекта attrib. Он определяет имя атрибута и устанавливает для него значение «Нет».

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()

# removing an attribute
root.attrib.pop('name', None)

# create a new XML file with the results
tree.write('newitems3.xml')

Результатом будет следующий XML-файл:

<data>
    <items>
        <item>item1abc</item>
        <item name="item2">item2abc</item>
    </items>
</data>

Как видно из XML-кода выше, первый элемент не имеет атрибута «name».

Удаление одного подэлемента

Один конкретный подэлемент можно удалить с помощью remove функции. Эта функция должна указать узел, который мы хотим удалить.

В следующем примере показано, как его использовать:

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()

# removing one sub-element
root.remove(root)

# create a new XML file with the results
tree.write('newitems4.xml')

Результатом будет следующий XML-файл:

<data>
    <items>
        <item name="item2">item2abc</item>
    </items>
</data>

Как видно из приведенного выше XML-кода, теперь есть только один узел «элемент». Второй был удален из исходного дерева.

Удаление всех подэлементов

В ElementTree модуле представляет нам с clear() функцией, которая может быть использована для удаления всех вложенных элементов данного элемента.

В приведенном ниже примере показано, как использовать clear():

import xml.etree.ElementTree as ET

tree = ET.parse('items.xml')
root = tree.getroot()

# removing all sub-elements of an element
root.clear()

# create a new XML file with the results
tree.write('newitems5.xml')

Результатом будет следующий XML-файл:

<data>
    <items />
</data>

Как видно из приведенного выше XML-кода, все подэлементы элемента «items» были удалены из дерева.

Заключение

Python предлагает несколько вариантов обработки файлов XML. В этой статье мы рассмотрели ElementTree модуль и использовали его для анализа, создания, изменения и удаления файлов XML. Мы также использовали minidom модель для анализа файлов XML. Лично я бы рекомендовал использовать этот ElementTree модуль, так как с ним намного проще работать и он является более современным модулем из двух.

Как конвертировать данные JSON в XML?

Теперь давайте конвертируем данные JSON в формат XML с помощью модуля XMLTODICT, сначала преобразовав данные JSON в словарь Python, используя Способ, а затем преобразование словаря на XML с помощью Отказ

Опять же, здесь ограничение это то, что Данные JSON должны иметь один корню В противном случае это будет причинить Отказ

#import module
import xmltodict
import json

#define dictionary with all the attributes
fileptr = open("/home/aditya1117/askpython/plane.json","r")
json_data=json.load(fileptr)
print("JSON data is:")
print(json_data)

#create xml format
xml_format= xmltodict.unparse(json_data,pretty=True)
print("XML format data is:")
print(xml_format)

Выход:

JSON data is:
{'plane': {'year': '1977', 'make': 'Cessna', 'model': 'Skyhawk', 'color': 'Light blue and white'}}
XML format data is:
<?xml version="1.0" encoding="utf-8"?>1977CessnaSkyhawkLight blue and white

В приведенном выше примере Принимает объект файла в качестве аргумента и анализа данных, которые создают тем самым словарь Python, который хранится в Отказ Затем мы преобразуем словарь в файл XML, используя метод.

Функции и операторы XPath

Вот 6 общих операторов, которые используются внутри запроса XPath. Операторы отмечают так же, как на простых питонах и служат той же цели. Функции предназначены для оказания поиска желаемых элементов или их содержания.

Выражение пути Результат
= Равно
!= Не равно
> Больше, чем
< Меньше чем
=> Больше или равно
=< Меньше или равно

Чтобы добавить дополнительную функциональность нашему выражению XPath, мы можем использовать некоторые функции библиотеки LXML. Все, что написано между «[]», называется предикатом, и он используется для более тесного описания пути поиска. Наиболее часто используемые функции являются и Отказ Эти функции и их результаты будут отображаться в таблице ниже.

Синтаксис YAML¶

Как и Python, YAML использует отступы для указания структуры документа.
Но в YAML можно использовать только пробелы и нельзя использовать знаки
табуляции.

Еще одна схожесть с Python: комментарии начинаются с символа # и
продолжаются до конца строки.

Список

Список может быть записан в одну строку:

switchport mode access, switchport access vlan, switchport nonegotiate, spanning-tree portfast, spanning-tree bpduguard enable

Или каждый элемент списка в своей строке:

- switchport mode access
- switchport access vlan
- switchport nonegotiate
- spanning-tree portfast
- spanning-tree bpduguard enable

Когда список записан таким блоком, каждая строка должна начинаться с
(минуса и пробела), и все строки в списке должны быть на одном
уровне отступа.

Словарь также может быть записан в одну строку:

{ vlan 100, name IT }

Или блоком:

vlan 100
name IT

Строки

Строки в YAML не обязательно брать в кавычки. Это удобно, но иногда всё
же следует использовать кавычки. Например, когда в строке используется
какой-то специальный символ (специальный для YAML).

Такую строку, например, нужно взять в кавычки, чтобы она была корректно
воспринята YAML:

command "sh interface | include Queueing strategy:"
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: