xml文档介绍

XML 指的是可扩展标记语言(eXtensible Markup Language),和json类似也是用于存储和传输数据,还可以用作配置文件。类似于HTML超文本标记语言,但是HTML所有的标签都是预定义的,而xml的标签可以随便定义。

  • 其它元素

    1. <aa>
    2. <bb></bb>
    3. </aa>
  • 属性

    1. <a id='123'></a>
  • 文本

    1. <a>abc</a>

    xml语法规则

  • 所有的元素都必须有开始标签和结束标签,省略结束标签是非法的

  • 大小写敏感,以下是俩个不同的标签
  • xml文档必须有根元素

    1. <note>
    2. <b>this is a test2</b>
    3. <name>joy</name>
    4. </note>
  • XML必须正确嵌套,父元素必须完全包住子元素

  • XML属性值必须加引号,元素的属性值都是一个键值对形式
  1. 名称可以包含字母、数字以及其他字符
    1. 名称不能以数字或标点符号开头
    2. 名称不能以字母xml或XML开始
    3. 名称不能包含空格
    4. 可以使用任何名称,没有保留字
    5. 名称应该具有描述性,简短和简单,可以同时使用下划线。
    6. 避免“-”、“.”、“:”等字符

      Python对XML的解析d


常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合也不同。python有三种方法解析XML:SAX,DOM和ElementTree

  1. DOM(Document Object Model)

DOM的解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后利用DOM提供的不同函数来读取该文档的内容和结构,也可以把修改过的内容写入XML文件。由于DOM是将XML读取到内存,然后解析成一个树,如果要处理的XML文本比较大的话,就会很耗内存,所以DOM一般偏向于处理一些小的XML,(如配置文件)比较快。

  1. SAX(simple API for XML)

Python标准库中包含SAX解析器,SAX是用的是事件驱动模型,通过在解析XML过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。解析的基本过程:
读到一个XML开始标签,就会开始一个事件,然后事件就会调用一系列的函数去处理一些事情,当读到一个结束标签时,就会触发另一个事件。所以,我们写XML文档入如果有格式错误的话,解析就会出错。这是一种流式处理,一边读一边解析,占用内存少。适用场景如下:

  1. 对大型文件进行处理;
  2. 只需要文件的部分内容,或者只需从文件中得到特定信息。
  3. 想建立自己的对象模型的时候。
    1. ElementTree(元素树)

ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

xml.dom解析xml


  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!--this is a test about xml.-->
  3. <booklist type="science and engineering">
  4. <book category="math">
  5. <title>learning math</title>
  6. <author>张三</author>
  7. <pageNumber>561</pageNumber>
  8. </book>
  9. <book category="Python">
  10. <title>learning Python</title>
  11. <author>李四</author>
  12. <pageNumber>600</pageNumber>
  13. </book>
  14. </booklist>
  1. from xml.dom.minidom import parse
  2. DOMTree = parse(r'book.xml')
  3. type(DOMTree)
  4. booklist = DOMTree.documentElement
  5. print(booklist.toxml(encoding=None))#输出xml文档内容
  6. >>>>
  7. <booklist type="science and engineering">
  8. <book category="math">
  9. <title>learning math</title>
  10. <author>张三</author>
  11. <pageNumber>561</pageNumber>
  12. </book>
  13. <book category="Python">
  14. <title>learning Python</title>
  15. <author>李四</author>
  16. <pageNumber>600</pageNumber>
  17. </book>
  18. </booklist>
  19. #getElementsByTagName(name)获取节点元素
  20. books=booklist.getElementsByTagName('book')
  21. print(books)
  22. >>[<DOM Element: book at 0x7fee90a015a0>, <DOM Element: book at 0x7fee90a01800>]
  23. print(books[0].toxml())
  24. >>>>
  25. <book category="math">
  26. <title>learning math</title>
  27. <author>张三</author>
  28. <pageNumber>561</pageNumber>
  29. </book>
  30. #hasAttribute(name)判断是否包含属性值
  31. if booklist.hasAttribute('type'):
  32. for book in books:
  33. if book.hasAttribute('category'):
  34. print(book.toxml())
  35. else:
  36. print("the book have no category")
  37. >>>>
  38. <book category="math">
  39. <title>learning math</title>
  40. <author>张三</author>
  41. <pageNumber>561</pageNumber>
  42. </book>
  43. <book category="Python">
  44. <title>learning Python</title>
  45. <author>李四</author>
  46. <pageNumber>600</pageNumber>
  47. </book>
  48. #node.getAttribute(name):获取节点node的属性值
  49. for book in books:
  50. print(book.getAttribute('category'))
  51. >>>>
  52. math
  53. Python
  54. #node.childNodes:返回节点node下所有的子节点组成的list
  55. for book in books:
  56. print(book.childNodes)
  57. >>>>
  58. [<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'">]
  59. [<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属性

  1. from xml.dom.minidom import parse
  2. DOMTree=parse(r'book.xml')
  3. booklist = DOMTree.documentElement
  4. print("booklist属性",booklist.nodeName,booklist.nodeValue,booklist.nodeType)
  5. >>booklist属性 booklist None 1 #nodeValue是结点的值,只对文本结点有效
  6. books = booklist.getElementsByTagName('book')
  7. for book in books:
  8. for node in book.childNodes:
  9. print(node)
  10. print(node.nodeName,node.nodeValue,node.nodeType)
  11. >>>>
  12. <DOM Text node "'\n \t'">
  13. #text
  14. 3
  15. <DOM Element: title at 0x7fee90a01638>
  16. title None 1
  17. <DOM Text node "'\n \t'">
  18. #text
  19. 3
  20. <DOM Element: author at 0x7fee90a016d0>
  21. author None 1
  22. #text
  23. 3
  24. pageNumber None 1
  25. #text
  26. 3
  27. #text
  28. 3
  29. title None 1
  30. #text
  31. 3
  32. author None 1
  33. #text
  34. 3
  35. pageNumber None 1
  36. #text
  37. 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文件


  1. 创建xml空白文档

    1. import xml.dom.minidom as xmldom
    2. doc = xmldom.Document()
    3. print(doc)
  2. 产生根对象

    1. import xml.dom.minidom as xmldom
    2. doc = xmldom.Document()
    3. root = doc.createElement('Manager')
    4. print('添加的xml标签为:',root.tagName)
  3. 向对象中加入数据

    1. import xml.dom.minidom as xmldom
    2. doc = xmldom.Document()
    3. root = doc.createElement('Manager')
    4. root.setAttribute('name','kongsh')
    5. value = root.getAttribute('name')
    6. print('root元素的name属性为:',value)
  4. 将xml内存对象写入文件

    1. import xml.dom.minidom as xmldom
    2. doc = xmldom.Document()
    3. root = doc.createElement('test')
    4. root.setAttribute('name','python')
    5. doc.appendChild(root)
    6. company = doc.createElement('gloryroad')
    7. name = doc.createElement('name')
    8. name.appendChild(doc.createTextNode('光荣之路'))
    9. ceo = doc.createElement('person')
    10. ceo.appendChild(doc.createTextNode('吴老师'))
    11. company.appendChild(name)
    12. company.appendChild(ceo)
    13. root.appendChild(company)
    14. print(doc.toxml())
  5. 生成xml文档

writexml(file,indent=’’,addindent=’’,newl=’’,encoding=None)
参数说明:

file 要保存的文件对象名
indent 根节点的缩进方式
addinent 子节点的缩进方式
newl 针对新行,指明换行方式
encoding 保存文件的编码方式
  1. import xml.dom.minidom as xmldom
  2. doc = xmldom.Document()
  3. fp = open(r'company.xml','w','utf-8')
  4. doc.writexml(fp,indent='',addindent='\t',newl='\n',encoding='utf-8')
  5. fp.close

字典转化为xml


parseString()解析字符串,toprettyxml格式化字符串,并写入xml文件

  1. import dicttoxml
  2. import os
  3. from xml.dom.minidom import parseString
  4. d = [20,'name',{'name':'Bill','age':30,'sex':'man'},{'name':'David','age':25,'sex':'man'},{'name':'Kell','age':33,'sex':'women'}]
  5. xml = dicttoxml.dicttoxml(d,custom_root='persons')
  6. preyxml = parseString(xml).toprettyxml(indent=' ')
  7. print(preyxml)
  8. >>>>
  9. <?xml version="1.0" ?>
  10. <persons>
  11. <item type="int">20</item>
  12. <item type="str">name</item>
  13. <item type="dict">
  14. <name type="str">Bill</name>
  15. <age type="int">30</age>
  16. <sex type="str">man</sex>
  17. </item>
  18. <item type="dict">
  19. <name type="str">David</name>
  20. <age type="int">25</age>
  21. <sex type="str">man</sex>
  22. </item>
  23. <item type="dict">
  24. <name type="str">Kell</name>
  25. <age type="int">33</age>
  26. <sex type="str">women</sex>
  27. </item>
  28. </persons>