如何在Python中获取xml中元素的值

2024-09-27 23:17:25 发布

您现在位置:Python中文网/ 问答频道 /正文

<?xml version="1.0" encoding="utf-8"?>
<bookstore name="Libreria Pastor">
    <book category="COOKING">
        <title lang="en">Everyday Italian</title>
        <author>
            <writer>Giada De Laurentiis</writer>
            <resumer>Pepe Lopez</resumer>
        </author>
        <year>2005</year>
        <price>30.00</price>
    </book>
    <book category="CHILDREN">
        <title lang="en">Harry Potter</title>
        <author>
            <writer>J K. Rowling</writer>
            <resumer>Ana Martinez</resumer>
        </author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book category="PROGRAMMING">
        <title lang="en">Python for All</title>
        <author>
            <writer>M.L. Jobs</writer>
            <resumer>Delton Jones</resumer>
        </author>
        <year>2015</year>
        <price>39.99</price>
    </book>
</bookstore>


from xml.dom import minidom
arbol_dom = minidom.parse('C:\\Users\\MiguelRG\\Desktop\\sge\\Pythons\\e3.xml')

listaBibliotecas = arbol_dom.getElementsByTagName("bookstore");
listaLibros = arbol_dom.getElementsByTagName("book");
listaAutores = arbol_dom.getElementsByTagName("author");

for biblioteca in listaBibliotecas: 
    print(biblioteca.tagName); 
    print("Nombre : " +biblioteca.getAttribute("name")); 
    print("Tiene hijos:"+str(biblioteca.hasChildNodes())); 
    for l in listaLibros:
        print("Tipo: "+l.tagName);
        print("Categoria: "+l.getAttribute("category")); 
        print("Titulo : " +l.childNodes[0].nodeValue);   
        print("Lenguaje : "+l.getAttribute("lang"));
        for a in listaAutores:
            **print("Escritor : " + str(a.childNodes[0].nodeValue));** 
            **print("Resumen por : "+str(a.childNodes[1].nodeValue));**
            break;

我想用这个程序或者类似的东西来阅读xml,但是我不能得到书名里面的信息和价格,我需要先打印书店的信息,然后是每本书的信息,然后是作者的信息

任何帮助都将受到感激

谢谢你


Tags: langfortitlexmlyearpricedomauthor
2条回答

xml文档中有很多节点。例如,与

<book>
    <title>I Am The Very Model</title>
</book>

title不是childNodes[0]。这是一个文本节点,换行符和<book><title>之间的空格。您需要在子节点中搜索title元素,最简单的方法是使用getElementsByTagName。一旦获得正确的元素,可能会有多个节点保存文本。您需要枚举所有这些文本才能找到所需的文本。您还需要决定节点周围的哪些空白位可以被剥离,否则可能会导致输出中出现奇怪的间隙

迁移到ElementTreelxml的一个原因是,它们倾向于整理这些内容,并为您提供一个更简单的API

您还需要注意调用getElementsByTagName的位置。当你做了listaAutores = arbol_dom.getElementsByTagName("author");你得到了文档中所有的作者,而你真的只是想要一本书的作者

作为旁白,去掉行末多余的分号。它们是不必要的,会让python程序员发疯

另一方面,print添加空格并将对象转换为字符串。只需使用它的功能,而不是字符串串联,这样您的代码就具有一致的外观和感觉

from xml.dom import minidom
arbol_dom = minidom.parse('test.xml')

def get_elem_text(elem):
    """join text in all immediate child text nodes"""
    return ''.join(node.data for node in elem.childNodes
        if node.nodeType == node.TEXT_NODE)

for biblioteca in arbol_dom.getElementsByTagName("bookstore"): 
    print(biblioteca.tagName) 
    print("Nombre :", biblioteca.getAttribute("name")) 
    print("Tiene hijos:", biblioteca.hasChildNodes()) 
    for l in biblioteca.getElementsByTagName("book"):
        print("Tipo:", l.tagName)
        print("Categoria:", l.getAttribute("category")) 
        print("Titulo :", get_elem_text(l.getElementsByTagName("title")[0]))   
        print("Lenguaje :", l.getAttribute("lang"))
        for a in l.getElementsByTagName("author"):
            print("Escritor :",
                get_elem_text(a.getElementsByTagName("writer")[0])) 
            print("Resumen por :",
                get_elem_text(a.getElementsByTagName("resumer")[0]))
            break

我建议使用xmltodict

import xmltodict

xml = None
with open('test.xml', 'r') as xmlfile:
    xml = xmlfile.read()
data = xmltodict.parse(xml)

books = data['bookstore']['book']

for book in books:
    print('\n      -')
    print(book['title']['#text'])
    print(book['author']['writer'])
    print(book['price'])
    print(book['year'])

输出如下所示:

      -
Everyday Italian
Giada De Laurentiis
30.00
2005

      -
Harry Potter
J K. Rowling
29.99
2005

      -
Python for All
M.L. Jobs
39.99
2015

你可以用pip安装它

pip install xmltodict

然后你可以在一个标准的dict中访问所有的信息

相关问题 更多 >

    热门问题