个性化阅读
专注于IT技术分析

带有ElementTree的Python XML:新手指南

点击下载

本文概述

作为数据科学家, 你会发现理解XML对于解析结构化文档的Web抓取和一般实践都具有强大的作用。

在本教程中, 你将涵盖以下主题:

  • 你将了解有关XML的更多信息, 并被介绍给Python ElementTree包。
  • 然后, 你将发现如何借助ElementTree函数(用于循环和XPath表达式)探索XML树, 以更好地理解正在使用的数据。
  • 接下来, 你将学习如何修改XML文件。和
  • 你将利用xpath表达来填充XML文件

什么是XML?

XML代表”可扩展标记语言”。它主要用于网页中, 其中数据具有特定的结构, 并且XML框架可以动态地理解该数据。

XML创建了易于解释并支持层次结构的树状结构。只要页面遵循XML, 便可以将其称为XML文档。

  • XML文档具有称为元素的部分, 由开始和结束标记定义。标记是一种标记构造, 以<开头, 以>结束。起始标签和结束标签之间的字符(如果有)是元素的内容。元素可以包含标记, 包括其他元素, 称为”子元素”。
  • 最大的顶级元素称为根, 其中包含所有其他元素。
  • 属性是存在于开始标记或空元素标记中的名称/值对。 XML属性只能有一个值, 并且每个属性在每个元素上最多可以出现一次。

为了更好地理解这一点, 请看以下(缩短的)XML文件:

<?xml version="1.0"?>
<collection>
    <genre category="Action">
        <decade years="1980s">
            <movie favorite="True" title="Indiana Jones: The raiders of the lost Ark">
                <format multiple="No">DVD</format>
                <year>1981</year>
                <rating>PG</rating>
                <description>
                'Archaeologist and adventurer Indiana Jones 
                is hired by the U.S. government to find the Ark of the 
                Covenant before the Nazis.'
                </description>
            </movie>
               <movie favorite="True" title="THE KARATE KID">
               <format multiple="Yes">DVD, Online</format>
               <year>1984</year>
               <rating>PG</rating>
               <description>None provided.</description>
            </movie>
            <movie favorite="False" title="Back 2 the Future">
               <format multiple="False">Blu-ray</format>
               <year>1985</year>
               <rating>PG</rating>
               <description>Marty McFly</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="False" title="X-Men">
               <format multiple="Yes">dvd, digital</format>
               <year>2000</year>
               <rating>PG-13</rating>
               <description>Two mutants come to a private academy for their kind whose resident superhero team must 
               oppose a terrorist organization with similar powers.</description>
            </movie>
            <movie favorite="True" title="Batman Returns">
               <format multiple="No">VHS</format>
               <year>1992</year>
               <rating>PG13</rating>
               <description>NA.</description>
            </movie>
               <movie favorite="False" title="Reservoir Dogs">
               <format multiple="No">Online</format>
               <year>1992</year>
               <rating>R</rating>
               <description>WhAtEvER I Want!!!?!</description>
            </movie>
        </decade>    
    </genre>

    <genre category="Thriller">
        <decade years="1970s">
            <movie favorite="False" title="ALIEN">
                <format multiple="Yes">DVD</format>
                <year>1979</year>
                <rating>R</rating>
                <description>"""""""""</description>
            </movie>
        </decade>
        <decade years="1980s">
            <movie favorite="True" title="Ferris Bueller's Day Off">
                <format multiple="No">DVD</format>
                <year>1986</year>
                <rating>PG13</rating>
                <description>Funny movie about a funny guy</description>
            </movie>
            <movie favorite="FALSE" title="American Psycho">
                <format multiple="No">blue-ray</format>
                <year>2000</year>
                <rating>Unrated</rating>
                <description>psychopathic Bateman</description>
            </movie>
        </decade>
    </genre>

通过上面的阅读, 你会看到

  • <collection>是单个根元素:它包含所有其他元素, 例如<genre>或<movie>, 它们是子元素或子元素。如你所见, 这些元素是嵌套的。

请注意, 这些子元素还可以充当父元素, 并包含其自己的子元素, 这些子元素随后称为”子子元素”。

  • 例如, 你将看到<movie>元素包含几个”属性”, 例如提供更多信息的收藏夹标题!

考虑到XML文件的简短介绍, 你就可以了解有关ElementTree的更多信息!

ElementTree简介

XML树结构使程序的导航, 修改和删除相对简单。 Python有一个内置的库ElementTree, 它具有读取和操作XML(以及其他类似结构的文件)的功能。

首先, 导入ElementTree。使用ET的别名是一种常见的做法:

import xml.etree.ElementTree as ET

解析XML数据

在提供的XML文件中, 描述了电影的基本集合。唯一的问题是数据很乱!这个馆藏有很多不同的策展人, 每个人都有自己的向文件中输入数据的方式。本教程的主要目标是使用Python阅读和理解文件-然后解决问题。

首先, 你需要使用ElementTree读取文件。

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

现在, 你已经初始化了树, 你应该查看XML并打印出值, 以了解树的结构。

树的每个部分(包括根)都有一个描述元素的标签。另外, 正如你在简介中所看到的, 元素可能具有属性, 这些属性是附加的描述符, 尤其用于重复使用标记。属性还有助于验证为该标签输入的值, 从而再次有助于XML的结构化格式。

你将在本教程的后面部分看到, 将属性包含在XML中时, 它们可以非常强大!

root.tag
'collection'

在顶层, 你可以看到该XML根植在collection标签中。

root.attrib
{}

因此, 根没有属性。

对于循环

你可以使用简单的” for”循环轻松遍历根中的子元素(通常称为”子元素”)。

for child in root:
    print(child.tag, child.attrib)
genre {'category': 'Action'}
genre {'category': 'Thriller'}
genre {'category': 'Comedy'}

现在你知道根集合的子代都是流派。为了指定类型, XML使用属性类别。根据体裁元素, 有动作, 惊悚和喜剧电影。

通常, 了解整个树中的所有元素会有所帮助。一个有用的功能是root.iter()。你可以将此函数放入” for”循环中, 它将遍历整个树。

[elem.tag for elem in root.iter()]
['collection', 'genre', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'movie', 'format', 'year', 'rating', 'description', 'movie', 'format', 'year', 'rating', 'description', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'movie', 'format', 'year', 'rating', 'description', 'movie', 'format', 'year', 'rating', 'description', 'genre', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'movie', 'format', 'year', 'rating', 'description', 'genre', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'movie', 'format', 'year', 'rating', 'description', 'decade', 'movie', 'format', 'year', 'rating', 'description', 'decade', 'movie', 'format', 'year', 'rating', 'description']

这给出了关于你有多少个元素的一般概念, 但没有显示树中的属性或级别。

有一种查看整个文档的有用方法。任何元素都具有.tostring()方法。如果将根传递给.tostring()方法, 则可以返回整个文档。在ElementTree中(请记住别名为ET), . tostring()的形式有点奇怪。

由于ElementTree是一个功能强大的库, 不仅可以解释XML, 还必须指定要显示为字符串的文档的编码和解码。对于XML, 请使用’utf8′-这是XML的典型文档格式类型。

print(ET.tostring(root, encoding='utf8').decode('utf8'))
<?xml version='1.0' encoding='utf8'?>
<collection>
    <genre category="Action">
        <decade years="1980s">
            <movie favorite="True" title="Indiana Jones: The raiders of the lost Ark">
                <format multiple="No">DVD</format>
                <year>1981</year>
                <rating>PG</rating>
                <description>
                'Archaeologist and adventurer Indiana Jones 
                is hired by the U.S. government to find the Ark of the 
                Covenant before the Nazis.'
                </description>
            </movie>
               <movie favorite="True" title="THE KARATE KID">
               <format multiple="Yes">DVD, Online</format>
               <year>1984</year>
               <rating>PG</rating>
               <description>None provided.</description>
            </movie>
            <movie favorite="False" title="Back 2 the Future">
               <format multiple="False">Blu-ray</format>
               <year>1985</year>
               <rating>PG</rating>
               <description>Marty McFly</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="False" title="X-Men">
               <format multiple="Yes">dvd, digital</format>
               <year>2000</year>
               <rating>PG-13</rating>
               <description>Two mutants come to a private academy for their kind whose resident superhero team must 
               oppose a terrorist organization with similar powers.</description>
            </movie>
            <movie favorite="True" title="Batman Returns">
               <format multiple="No">VHS</format>
               <year>1992</year>
               <rating>PG13</rating>
               <description>NA.</description>
            </movie>
               <movie favorite="False" title="Reservoir Dogs">
               <format multiple="No">Online</format>
               <year>1992</year>
               <rating>R</rating>
               <description>WhAtEvER I Want!!!?!</description>
            </movie>
        </decade>    
    </genre>

    <genre category="Thriller">
        <decade years="1970s">
            <movie favorite="False" title="ALIEN">
                <format multiple="Yes">DVD</format>
                <year>1979</year>
                <rating>R</rating>
                <description>"""""""""</description>
            </movie>
        </decade>
        <decade years="1980s">
            <movie favorite="True" title="Ferris Bueller's Day Off">
                <format multiple="No">DVD</format>
                <year>1986</year>
                <rating>PG13</rating>
                <description>Funny movie about a funny guy</description>
            </movie>
            <movie favorite="FALSE" title="American Psycho">
                <format multiple="No">blue-ray</format>
                <year>2000</year>
                <rating>Unrated</rating>
                <description>psychopathic Bateman</description>
            </movie>
        </decade>
    </genre>

    <genre category="Comedy">
        <decade years="1960s">
            <movie favorite="False" title="Batman: The Movie">
                <format multiple="Yes">DVD, VHS</format>
                <year>1966</year>
                <rating>PG</rating>
                <description>What a joke!</description>
            </movie>
        </decade>
        <decade years="2010s">
            <movie favorite="True" title="Easy A">
                <format multiple="No">DVD</format>
                <year>2010</year>
                <rating>PG--13</rating>
                <description>Emma Stone = Hester Prynne</description>
            </movie>
            <movie favorite="True" title="Dinner for SCHMUCKS">
                <format multiple="Yes">DVD, digital, Netflix</format>
                <year>2011</year>
                <rating>Unrated</rating>
                <description>Tim (Rudd) is a rising executive
                 who "succeeds" in finding the perfect guest, IRS employee Barry (Carell), for his boss’ monthly event, a so-called "dinner for idiots, " which offers certain 
                 advantages to the exec who shows up with the biggest buffoon.
                 </description>
            </movie>
        </decade>
        <decade years="1980s">
            <movie favorite="False" title="Ghostbusters">
                <format multiple="No">Online, VHS</format>
                <year>1984</year>
                <rating>PG</rating>
                <description>Who ya gonna call?</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="True" title="Robin Hood: Prince of Thieves">
                <format multiple="No">Blu_Ray</format>
                <year>1991</year>
                <rating>Unknown</rating>
                <description>Robin Hood slaying</description>
            </movie>
        </decade>
    </genre>
</collection>

你可以扩展使用iter()函数来帮助查找感兴趣的特定元素。 root.iter()将列出根目录下与指定元素匹配的所有子元素。在这里, 你将在树中列出movie元素的所有属性:

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'}

你已经可以看到以不同方式输入电影的方式。现在不用担心, 你将有机会在本教程后面的错误中进行修复。

XPath表达式

很多时候元素不会具有属性, 而只会具有文本内容。使用属性.text, 可以打印出此内容。

现在, 打印出电影的所有描述。

for description in root.iter('description'):
    print(description.text)
                'Archaeologist and adventurer Indiana Jones 
                is hired by the U.S. government to find the Ark of the 
                Covenant before the Nazis.'

None provided.
Marty McFly
Two mutants come to a private academy for their kind whose resident superhero team must 
               oppose a terrorist organization with similar powers.
NA.
WhAtEvER I Want!!!?!
"""""""""
Funny movie about a funny guy
psychopathic Bateman
What a joke!
Emma Stone = Hester Prynne
Tim (Rudd) is a rising executive
                 who "succeeds" in finding the perfect guest, IRS employee Barry (Carell), for his boss’ monthly event, a so-called "dinner for idiots, " which offers certain 
                 advantages to the exec who shows up with the biggest buffoon.

Who ya gonna call?
Robin Hood slaying

打印出XML是有帮助的, 但是XPath是一种查询语言, 用于快速, 轻松地搜索XML。 XPath代表XML路径语言, 顾名思义, 它使用”类似路径”的语法来标识和导航XML文档中的节点。

了解XPath对于扫描和填充XML至关重要。 ElementTree具有.findall()函数, 该函数将遍历所引用元素的直接子级。你可以使用XPath表达式来指定更有用的搜索。

在这里, 你将在树上搜索1992年发行的电影:

for movie in root.findall("./genre/decade/movie/[year='1992']"):
    print(movie.attrib)
{'favorite': 'True', 'title': 'Batman Returns'}
{'favorite': 'False', 'title': 'Reservoir Dogs'}

函数.findall()始终从指定的元素开始。这种功能对于”查找和替换”而言非常强大。你甚至可以搜索属性!

现在, 仅打印出多种格式(属性)可用的电影。

for movie in root.findall("./genre/decade/movie/format/[@multiple='Yes']"):
    print(movie.attrib)
{'multiple': 'Yes'}
{'multiple': 'Yes'}
{'multiple': 'Yes'}
{'multiple': 'Yes'}
{'multiple': 'Yes'}

头脑风暴, 为什么在这种情况下, 打印语句返回” Yes”值(倍数)。考虑一下” for”循环的定义。你可以重写此循环以打印电影标题吗?在下面尝试:

提示:在XPath内部使用’…’返回当前元素的父元素。

for movie in root.findall("./genre/decade/movie/format[@multiple='Yes']..."):
    print(movie.attrib)
{'favorite': 'True', 'title': 'THE KARATE KID'}
{'favorite': 'False', 'title': 'X-Men'}
{'favorite': 'False', 'title': 'ALIEN'}
{'favorite': 'False', 'title': 'Batman: The Movie'}
{'favorite': 'True', 'title': 'Dinner for SCHMUCKS'}

修改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中修复” 2″。那应该是一个发现并替换的问题。编写代码以找到标题” Back 2 the Future”并将其保存为变量:

b2tf = root.find("./genre/decade/movie[@title='Back 2 the Future']")
print(b2tf)
<Element 'movie' at 0x10ce00ef8>

请注意, 使用.find()方法将返回树的元素。在很多时候, 编辑元素中的内容会更加有用。

修改Back 2 Future元素变量的title属性, 使其显示为” Back to the Future”。然后, 打印出变量的属性以查看更改。你可以通过访问元素的属性然后为它分配一个新值来轻松地做到这一点:

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

将所做的更改写回XML, 以便将其永久固定在文档中。再次打印出电影属性, 以确保所做的更改有效。使用.write()方法执行以下操作:

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'}

固定属性

在某些地方, multiple属性不正确。使用ElementTree根据影片进入的格式来固定指示符。首先, 打印格式属性和文本以查看需要固定的部分。

for form in root.findall("./genre/decade/movie/format"):
    print(form.attrib, form.text)
{'multiple': 'No'} DVD
{'multiple': 'Yes'} DVD, Online
{'multiple': 'False'} Blu-ray
{'multiple': 'Yes'} dvd, digital
{'multiple': 'No'} VHS
{'multiple': 'No'} Online
{'multiple': 'Yes'} DVD
{'multiple': 'No'} DVD
{'multiple': 'No'} blue-ray
{'multiple': 'Yes'} DVD, VHS
{'multiple': 'No'} DVD
{'multiple': 'Yes'} DVD, digital, Netflix
{'multiple': 'No'} Online, VHS
{'multiple': 'No'} Blu_Ray

在此标签上需要完成一些工作。

你可以使用正则表达式查找逗号-这将告诉你Multiple属性应为”是”还是”否”。使用.set()方法可以轻松地添加和修改属性。

注意:re是Python的标准正则表达式解释器。如果你想进一步了解正则表达式, 请考虑本教程。

import re

for form in root.findall("./genre/decade/movie/format"):
    # Search for the commas in the format text
    match = re.search(', ', form.text)
    if match:
        form.set('multiple', 'Yes')
    else:
        form.set('multiple', 'No')

# Write out the tree to the file again
tree.write("movies.xml")

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

for form in root.findall("./genre/decade/movie/format"):
    print(form.attrib, form.text)
{'multiple': 'No'} DVD
{'multiple': 'Yes'} DVD, Online
{'multiple': 'No'} Blu-ray
{'multiple': 'Yes'} dvd, digital
{'multiple': 'No'} VHS
{'multiple': 'No'} Online
{'multiple': 'No'} DVD
{'multiple': 'No'} DVD
{'multiple': 'No'} blue-ray
{'multiple': 'Yes'} DVD, VHS
{'multiple': 'No'} DVD
{'multiple': 'Yes'} DVD, digital, Netflix
{'multiple': 'Yes'} Online, VHS
{'multiple': 'No'} Blu_Ray

运动元素

一些数据被放置在错误的十年中。使用对XML和ElementTree的了解来查找和修复十年数据错误。

在整个文档中打印出十年标记和年份标记将很有用。

for decade in root.findall("./genre/decade"):
    print(decade.attrib)
    for year in decade.findall("./movie/year"):
        print(year.text, '\n')
{'years': '1980s'}
1981 

1984 

1985 

{'years': '1990s'}
2000 

1992 

1992 

{'years': '1970s'}
1979 

{'years': '1980s'}
1986 

2000 

{'years': '1960s'}
1966 

{'years': '2010s'}
2010 

2011 

{'years': '1980s'}
1984 

{'years': '1990s'}
1991 

错误的十年是2000年代的电影。使用XPath表达式找出这些电影是什么。

for movie in root.findall("./genre/decade/movie/[year='2000']"):
    print(movie.attrib)
{'favorite': 'False', 'title': 'X-Men'}
{'favorite': 'FALSE', 'title': 'American Psycho'}

你必须在”动作”类型中添加新的十年标记(即2000年代), 才能移动X战警数据。 .SubElement()方法可用于将此标签添加到XML的末尾。

action = root.find("./genre[@category='Action']")
new_dec = ET.SubElement(action, 'decade')
new_dec.attrib["years"] = '2000s'

print(ET.tostring(action, encoding='utf8').decode('utf8'))
<?xml version='1.0' encoding='utf8'?>
<genre category="Action">
        <decade years="1980s">
            <movie favorite="True" title="Indiana Jones: The raiders of the lost Ark">
                <format multiple="No">DVD</format>
                <year>1981</year>
                <rating>PG</rating>
                <description>
                'Archaeologist and adventurer Indiana Jones 
                is hired by the U.S. government to find the Ark of the 
                Covenant before the Nazis.'
                </description>
            </movie>
               <movie favorite="True" title="THE KARATE KID">
               <format multiple="Yes">DVD, Online</format>
               <year>1984</year>
               <rating>PG</rating>
               <description>None provided.</description>
            </movie>
            <movie favorite="False" title="Back to the Future">
               <format multiple="No">Blu-ray</format>
               <year>1985</year>
               <rating>PG</rating>
               <description>Marty McFly</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="False" title="X-Men">
               <format multiple="Yes">dvd, digital</format>
               <year>2000</year>
               <rating>PG-13</rating>
               <description>Two mutants come to a private academy for their kind whose resident superhero team must 
               oppose a terrorist organization with similar powers.</description>
            </movie>
            <movie favorite="True" title="Batman Returns">
               <format multiple="No">VHS</format>
               <year>1992</year>
               <rating>PG13</rating>
               <description>NA.</description>
            </movie>
               <movie favorite="False" title="Reservoir Dogs">
               <format multiple="No">Online</format>
               <year>1992</year>
               <rating>R</rating>
               <description>WhAtEvER I Want!!!?!</description>
            </movie>
        </decade>    
    <decade years="2000s" /></genre>

现在将X战警电影追加到2000年代, 并分别使用.append()和.remove()从1990年代将其删除。

xmen = root.find("./genre/decade/movie[@title='X-Men']")
dec2000s = root.find("./genre[@category='Action']/decade[@years='2000s']")
dec2000s.append(xmen)
dec1990s = root.find("./genre[@category='Action']/decade[@years='1990s']")
dec1990s.remove(xmen)

print(ET.tostring(action, encoding='utf8').decode('utf8'))
<?xml version='1.0' encoding='utf8'?>
<genre category="Action">
        <decade years="1980s">
            <movie favorite="True" title="Indiana Jones: The raiders of the lost Ark">
                <format multiple="No">DVD</format>
                <year>1981</year>
                <rating>PG</rating>
                <description>
                'Archaeologist and adventurer Indiana Jones 
                is hired by the U.S. government to find the Ark of the 
                Covenant before the Nazis.'
                </description>
            </movie>
               <movie favorite="True" title="THE KARATE KID">
               <format multiple="Yes">DVD, Online</format>
               <year>1984</year>
               <rating>PG</rating>
               <description>None provided.</description>
            </movie>
            <movie favorite="False" title="Back to the Future">
               <format multiple="No">Blu-ray</format>
               <year>1985</year>
               <rating>PG</rating>
               <description>Marty McFly</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="True" title="Batman Returns">
               <format multiple="No">VHS</format>
               <year>1992</year>
               <rating>PG13</rating>
               <description>NA.</description>
            </movie>
               <movie favorite="False" title="Reservoir Dogs">
               <format multiple="No">Online</format>
               <year>1992</year>
               <rating>R</rating>
               <description>WhAtEvER I Want!!!?!</description>
            </movie>
        </decade>    
    <decade years="2000s"><movie favorite="False" title="X-Men">
               <format multiple="Yes">dvd, digital</format>
               <year>2000</year>
               <rating>PG-13</rating>
               <description>Two mutants come to a private academy for their kind whose resident superhero team must 
               oppose a terrorist organization with similar powers.</description>
            </movie>
            </decade></genre>

建立XML文件

很好, 因此你基本上可以将整部电影移至新的十年。将你的更改保存回XML。

tree.write("movies.xml")

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

print(ET.tostring(root, encoding='utf8').decode('utf8'))
<?xml version='1.0' encoding='utf8'?>
<collection>
    <genre category="Action">
        <decade years="1980s">
            <movie favorite="True" title="Indiana Jones: The raiders of the lost Ark">
                <format multiple="No">DVD</format>
                <year>1981</year>
                <rating>PG</rating>
                <description>
                'Archaeologist and adventurer Indiana Jones 
                is hired by the U.S. government to find the Ark of the 
                Covenant before the Nazis.'
                </description>
            </movie>
               <movie favorite="True" title="THE KARATE KID">
               <format multiple="Yes">DVD, Online</format>
               <year>1984</year>
               <rating>PG</rating>
               <description>None provided.</description>
            </movie>
            <movie favorite="False" title="Back to the Future">
               <format multiple="No">Blu-ray</format>
               <year>1985</year>
               <rating>PG</rating>
               <description>Marty McFly</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="True" title="Batman Returns">
               <format multiple="No">VHS</format>
               <year>1992</year>
               <rating>PG13</rating>
               <description>NA.</description>
            </movie>
               <movie favorite="False" title="Reservoir Dogs">
               <format multiple="No">Online</format>
               <year>1992</year>
               <rating>R</rating>
               <description>WhAtEvER I Want!!!?!</description>
            </movie>
        </decade>    
    <decade years="2000s"><movie favorite="False" title="X-Men">
               <format multiple="Yes">dvd, digital</format>
               <year>2000</year>
               <rating>PG-13</rating>
               <description>Two mutants come to a private academy for their kind whose resident superhero team must 
               oppose a terrorist organization with similar powers.</description>
            </movie>
            </decade></genre>

    <genre category="Thriller">
        <decade years="1970s">
            <movie favorite="False" title="ALIEN">
                <format multiple="No">DVD</format>
                <year>1979</year>
                <rating>R</rating>
                <description>"""""""""</description>
            </movie>
        </decade>
        <decade years="1980s">
            <movie favorite="True" title="Ferris Bueller's Day Off">
                <format multiple="No">DVD</format>
                <year>1986</year>
                <rating>PG13</rating>
                <description>Funny movie about a funny guy</description>
            </movie>
            <movie favorite="FALSE" title="American Psycho">
                <format multiple="No">blue-ray</format>
                <year>2000</year>
                <rating>Unrated</rating>
                <description>psychopathic Bateman</description>
            </movie>
        </decade>
    </genre>

    <genre category="Comedy">
        <decade years="1960s">
            <movie favorite="False" title="Batman: The Movie">
                <format multiple="Yes">DVD, VHS</format>
                <year>1966</year>
                <rating>PG</rating>
                <description>What a joke!</description>
            </movie>
        </decade>
        <decade years="2010s">
            <movie favorite="True" title="Easy A">
                <format multiple="No">DVD</format>
                <year>2010</year>
                <rating>PG--13</rating>
                <description>Emma Stone = Hester Prynne</description>
            </movie>
            <movie favorite="True" title="Dinner for SCHMUCKS">
                <format multiple="Yes">DVD, digital, Netflix</format>
                <year>2011</year>
                <rating>Unrated</rating>
                <description>Tim (Rudd) is a rising executive
                 who "succeeds" in finding the perfect guest, IRS employee Barry (Carell), for his boss’ monthly event, a so-called "dinner for idiots, " which offers certain 
                 advantages to the exec who shows up with the biggest buffoon.
                 </description>
            </movie>
        </decade>
        <decade years="1980s">
            <movie favorite="False" title="Ghostbusters">
                <format multiple="Yes">Online, VHS</format>
                <year>1984</year>
                <rating>PG</rating>
                <description>Who ya gonna call?</description>
            </movie>
        </decade>
        <decade years="1990s">
            <movie favorite="True" title="Robin Hood: Prince of Thieves">
                <format multiple="No">Blu_Ray</format>
                <year>1991</year>
                <rating>Unknown</rating>
                <description>Robin Hood slaying</description>
            </movie>
        </decade>
    </genre>
</collection>

总结

关于XML和使用ElementTree, 需要记住一些关键的事情。

标签建立树形结构并指定应在此处描述的值。使用智能结构可以使读取和写入XML变得容易。标签始终需要用方括号括起来以显示父子关系。

属性还描述了如何验证标签或允许使用布尔值指定。属性通常采用非常特定的值, 以便XML解析器(和用户)可以使用属性来检查标记值。

ElementTree是一个重要的Python库, 允许你解析和导航XML文档。使用ElementTree可将XML文档分解为易于使用的树形结构。如有疑问, 请打印出来(print(ET.tostring(root, encoding =’utf8′)。decode(‘utf8’)))-使用此有用的打印语句可一次查看整个XML文档。它有助于检查何时编辑, 添加或从XML中删除。

现在, 你已经具备了了解XML并开始解析的能力!

参考文献:

  • https://docs.python.org/3.5/library/xml.etree.elementtree.html
  • https://en.wikipedia.org/wiki/XML
赞(0)
未经允许不得转载:srcmini » 带有ElementTree的Python XML:新手指南

评论 抢沙发

评论前必须登录!