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 parseDOMTree = parse(r'book.xml')type(DOMTree)booklist = DOMTree.documentElementprint(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'))>>>>mathPython#node.childNodes:返回节点node下所有的子节点组成的listfor 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 parseDOMTree=parse(r'book.xml')booklist = DOMTree.documentElementprint("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'">#text3<DOM Element: title at 0x7fee90a01638>title None 1<DOM Text node "'\n \t'">#text3<DOM Element: author at 0x7fee90a016d0>author None 1#text3pageNumber None 1#text3#text3title None 1#text3author None 1#text3pageNumber None 1#text3
主要方法总结
| 方法 | 描述 | ||
|---|---|---|---|
| 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 xmldomdoc = xmldom.Document()print(doc)
产生根对象
import xml.dom.minidom as xmldomdoc = xmldom.Document()root = doc.createElement('Manager')print('添加的xml标签为:',root.tagName)
向对象中加入数据
import xml.dom.minidom as xmldomdoc = xmldom.Document()root = doc.createElement('Manager')root.setAttribute('name','kongsh')value = root.getAttribute('name')print('root元素的name属性为:',value)
将xml内存对象写入文件
import xml.dom.minidom as xmldomdoc = 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 xmldomdoc = 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 dicttoxmlimport osfrom xml.dom.minidom import parseStringd = [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>
