xml文档介绍
XML 指的是可扩展标记语言(eXtensible Markup Language),和json类似也是用于存储和传输数据,还可以用作配置文件。类似于HTML超文本标记语言,但是HTML所有的标签都是预定义的,而xml的标签可以随便定义。
其它元素
<aa>
<bb></bb>
</aa>
属性
<a id='123'></a>
文本
<a>abc</a>
xml语法规则
所有的元素都必须有开始标签和结束标签,省略结束标签是非法的
- 大小写敏感,以下是俩个不同的标签
xml文档必须有根元素
<note>
<b>this is a test2</b>
<name>joy</name>
</note>
XML必须正确嵌套,父元素必须完全包住子元素
- XML属性值必须加引号,元素的属性值都是一个键值对形式
- 名称可以包含字母、数字以及其他字符
常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。python有三种方法解析XML:SAX,DOM和ElementTree
- DOM(Document Object Model)
DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件。由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文本比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML,(如配置文件)比较快。
- SAX(simple API for XML)
Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。解析的基本过程:
读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档入如果有格式错误的话,解析就会出错。这是一种流式处理,一边读一边解析,占用内存少。适用场景如下:
- 对大型文件进行处理;
- 只需要文件的部分内容,或者只需从文件中得到特定信息。
- 想建立自己的对象模型的时候。
- ElementTree(元素树)
ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。
xml.dom解析xml
<?xml version="1.0" encoding="utf-8" ?>
<!--this is a test about xml.-->
<booklist type="science and engineering">
<book category="math">
<title>learning math</title>
<author>张三</author>
<pageNumber>561</pageNumber>
</book>
<book category="Python">
<title>learning Python</title>
<author>李四</author>
<pageNumber>600</pageNumber>
</book>
</booklist>
from xml.dom.minidom import parse
DOMTree = parse(r'book.xml')
type(DOMTree)
booklist = DOMTree.documentElement
print(booklist.toxml(encoding=None))#输出xml文档内容
>>>>
<booklist type="science and engineering">
<book category="math">
<title>learning math</title>
<author>张三</author>
<pageNumber>561</pageNumber>
</book>
<book category="Python">
<title>learning Python</title>
<author>李四</author>
<pageNumber>600</pageNumber>
</book>
</booklist>
#getElementsByTagName(name)获取节点元素
books=booklist.getElementsByTagName('book')
print(books)
>>[<DOM Element: book at 0x7fee90a015a0>, <DOM Element: book at 0x7fee90a01800>]
print(books[0].toxml())
>>>>
<book category="math">
<title>learning math</title>
<author>张三</author>
<pageNumber>561</pageNumber>
</book>
#hasAttribute(name)判断是否包含属性值
if booklist.hasAttribute('type'):
for book in books:
if book.hasAttribute('category'):
print(book.toxml())
else:
print("the book have no category")
>>>>
<book category="math">
<title>learning math</title>
<author>张三</author>
<pageNumber>561</pageNumber>
</book>
<book category="Python">
<title>learning Python</title>
<author>李四</author>
<pageNumber>600</pageNumber>
</book>
#node.getAttribute(name):获取节点node的属性值
for book in books:
print(book.getAttribute('category'))
>>>>
math
Python
#node.childNodes:返回节点node下所有的子节点组成的list
for book in books:
print(book.childNodes)
>>>>
[<DOM Text node "'\n \t'">, <DOM Element: title at 0x7fee90a01638>, <DOM Text node "'\n \t'">, <DOM Element: author at 0x7fee90a016d0>, <DOM Text node "'\n \t'">, <DOM Element: pageNumber at 0x7fee90a01768>, <DOM Text node "'\n \t'">]
[<DOM Text node "'\n \t'">, <DOM Element: title at 0x7fee90a01898>, <DOM Text node "'\n \t'">, <DOM Element: author at 0x7fee90a01930>, <DOM Text node "'\n \t'">, <DOM Element: pageNumber at 0x7fee90a019c8>, <DOM Text node "'\n \t'">]
获取标签属性
每一个节点都有它的nodeName, nodeValue, nodeType属性
from xml.dom.minidom import parse
DOMTree=parse(r'book.xml')
booklist = DOMTree.documentElement
print("booklist属性",booklist.nodeName,booklist.nodeValue,booklist.nodeType)
>>booklist属性 booklist None 1 #nodeValue是结点的值,只对文本结点有效
books = booklist.getElementsByTagName('book')
for book in books:
for node in book.childNodes:
print(node)
print(node.nodeName,node.nodeValue,node.nodeType)
>>>>
<DOM Text node "'\n \t'">
#text
3
<DOM Element: title at 0x7fee90a01638>
title None 1
<DOM Text node "'\n \t'">
#text
3
<DOM Element: author at 0x7fee90a016d0>
author None 1
#text
3
pageNumber None 1
#text
3
#text
3
title None 1
#text
3
author None 1
#text
3
pageNumber None 1
#text
3
主要方法总结
方法 | 描述 | ||
---|---|---|---|
mindom.parse(filename) | 加载读取xml文件 | ||
doc.documentElement | 获取xml文档对象 | ||
node.getAttribute(AttributeName) | 获取xml节点属性值 | ||
node.getElementsByTagName(TagName) | 获取xml节点对象集合 | ||
node.childNodes | 返回子节点列表 | ||
node.childNodes[index].nodeValue | 获取xml节点值 | ||
node.firstChild | 访问第一个节点,等价于pagexml.childNodes[0] | ||
doc.toxml() | 返回node节点的xml表示文本 | ||
Node.attribute[‘id’] | 访问元素属性 | ||
a.name | 上面的’id’ | ||
a.value | 属性的值 | ||
root.nodeName/root.tagName | 节点的名称 | ||
root.nodeValue | 节点的值,文本节点才有值,其它节点返回的是None | ||
root.nodeType |
节点的类型 |
1 | ELEMENT_NODE |
2 | ATTRIBUTE_NODE | ||
3 | TEXT_NODE | ||
4 | CDATA_SECTION_NODE | ||
5 | ENTITY_REFERENCE_NODE | ||
6 | ENTITY_NODE | ||
7 | PROCESSING_INSTRUCTION_NODE | ||
8 | COMMENT_NODE | ||
9 | DOCUMENT_NODE |
xml.dom创建xml文件
创建xml空白文档
import xml.dom.minidom as xmldom
doc = xmldom.Document()
print(doc)
产生根对象
import xml.dom.minidom as xmldom
doc = xmldom.Document()
root = doc.createElement('Manager')
print('添加的xml标签为:',root.tagName)
向对象中加入数据
import xml.dom.minidom as xmldom
doc = xmldom.Document()
root = doc.createElement('Manager')
root.setAttribute('name','kongsh')
value = root.getAttribute('name')
print('root元素的name属性为:',value)
将xml内存对象写入文件
import xml.dom.minidom as xmldom
doc = xmldom.Document()
root = doc.createElement('test')
root.setAttribute('name','python')
doc.appendChild(root)
company = doc.createElement('gloryroad')
name = doc.createElement('name')
name.appendChild(doc.createTextNode('光荣之路'))
ceo = doc.createElement('person')
ceo.appendChild(doc.createTextNode('吴老师'))
company.appendChild(name)
company.appendChild(ceo)
root.appendChild(company)
print(doc.toxml())
生成xml文档
writexml(file,indent=’’,addindent=’’,newl=’’,encoding=None)
参数说明:
file | 要保存的文件对象名 |
---|---|
indent | 根节点的缩进方式 |
addinent | 子节点的缩进方式 |
newl | 针对新行,指明换行方式 |
encoding | 保存文件的编码方式 |
import xml.dom.minidom as xmldom
doc = xmldom.Document()
fp = open(r'company.xml','w','utf-8')
doc.writexml(fp,indent='',addindent='\t',newl='\n',encoding='utf-8')
fp.close
字典转化为xml
parseString()解析字符串,toprettyxml格式化字符串,并写入xml文件
import dicttoxml
import os
from xml.dom.minidom import parseString
d = [20,'name',{'name':'Bill','age':30,'sex':'man'},{'name':'David','age':25,'sex':'man'},{'name':'Kell','age':33,'sex':'women'}]
xml = dicttoxml.dicttoxml(d,custom_root='persons')
preyxml = parseString(xml).toprettyxml(indent=' ')
print(preyxml)
>>>>
<?xml version="1.0" ?>
<persons>
<item type="int">20</item>
<item type="str">name</item>
<item type="dict">
<name type="str">Bill</name>
<age type="int">30</age>
<sex type="str">man</sex>
</item>
<item type="dict">
<name type="str">David</name>
<age type="int">25</age>
<sex type="str">man</sex>
</item>
<item type="dict">
<name type="str">Kell</name>
<age type="int">33</age>
<sex type="str">women</sex>
</item>
</persons>