格式化存储
XML文件操作
XML 指可扩展标记语言
-
XML不是对HTML的替代;XML是对HTML的补充;
- HTML:被设计用来显示数据;焦点是数据的外观
- XML被设计用来传输和存储数据;焦点是数据的内容
-
是w3c的推荐标准(1998.2.10)
-
XML简化数据共享
- XML以纯文本格式存储,因此提供了一种独立于软件和硬件的数据存储方法
-
XML简化数据传输
- XML是一种独立于软件和硬件的信息传输工具
-
XML文档的树结构
- 它从“根部”开始,然后扩展到“枝叶”。
- 案例:
<?xml version="1.0" encoding="ISO-8859-1"?> # XML声明:定义 XML 的版本 (1.0) 和所使用的编码 (ISO-8859-1 = Latin-1/西欧字符集)
<note> #文档的根元素
<to>George</to> #4 个子元素
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note> #根元素的结尾
XML语法规则
- XML 标签对大小写敏感
- 所有 XML 元素都须有关闭标签
- XML 文档必须有根元素
- XML 的属性值须加引号
- 保留字符处理:
- 使用实体引用(EntityReference)来表示保留字符,即转义
- 或者把含有保留字符的步伐放在CDATA块内部,CDATA块把内部信息视为不需要转义
< < 小于
> > 大于
& & 和号
' ' 单引号
" " 引号
示例:
<score> score>80 </score>
<score> score>80 </score>
<![CDATA[
SELECT name,age from Student where score > 80
]]>
- 注释语法:
- 在 XML 中,空格会被保留(不删除)
- 命名空间
- 为了防止命名冲突
- 为了避免冲突,需要给可能冲突元素添加命名空间
- xmlns:xml name space 的缩写
<Schoolsr xmlns:student="http://my_student" xmlns:room="http://my_room">
XML元素和属性
- XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。
- 案例: 和 都拥有元素内容,因为它们包含了其他元素。 只有文本内容,因为它仅包含文本。
<bookstore>
<book category="CHILDREN">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
- 属性(Attribute):提供关于元素的额外(附加)信息
- XML属性必须加引号:
- 请尽量使用元素来描述数据。而仅仅使用属性来提供与数据无关的信息(使用子元素)
XML的访问
- xml读取分两个主要技术:SAX,DOM
- SAX(Simple API for XML)
- 基于事件驱动的API
- 利用SAX解析文档设计到解析器和事件处理两部分
- 特点:快;流式读取;
- DOM
- 是W3C规定的XML编程接口
- 一个XML文件在缓存中以树形结构保存,读取
- SAX(Simple API for XML)
XML DOM(Document Object Model,文档对象模型)
- DOM是W3C的推荐标准,定义了访问诸如XML和XHTML文档的标准。
- XML DOM定义了所有XML元素的对象和属性,以及访问它们的方法(接口)
- DOM 把XML文档作为树结构来查看。通过DOM树来访问所有元素
- 可以修改或删除它们的内容,并创建新的元素。元素,它们的文本,以及它们的属性,都被认为是节点
- XML文档中的每个成分都是一个节点。
- XML DOM把XML DOM文档视为一棵节点树(node-tree),树中的所有节点彼此之间都有关系
- 方法
xmlDoc -由解析器创建的 XML 文档
getElementsByTagName(“to”)[0] - 第一个 元素
childNodes[0] - 元素的第一个子元素(文本节点)
nodeValue - 节点的值(文本本身)
Python minidom模块(DOM写入和解析XML)
- DOM写XML文件(示例来源:https://www.cnblogs.com/wcwnina/p/7222180.html)
from xml.dom import minidom
# 1.创建DOM树对象
dom = minidom.Document()
# 2.创建根节点。每次都要用DOM对象来创建任何节点。
root_node = dom.createElement('root')
# 3.用DOM对象添加根节点
dom.appendChild(root_node)
# 用DOM对象创建元素子节点
book_node = dom.createElement('book')
# 用父节点对象添加元素子节点
root_node.appendChild(book_node)
# 设置该节点的属性
book_node.setAttribute('price','199')
name_node = dom.createElement('name')
root_node.appendChild(name_node)
# 也用DOM创建文本节点,把文本节点(文字内容)看成子节点
name_text = dom.createTextNode('Price c++')
# 用添加了文本的节点对象(看成文本节点的父节点)添加文本节点
name_node.appendChild(name_text)
try:
with open('dom_write.xml', 'w', encoding='UTF-8') as fh:
#writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式,第四个参数制定了换行格式,第五个参数制定了xml内容的编码。
dom.writexml(fh, indent='',addindent='\t', newl='\n', encoding='UTF-8')
print ("wirte ok")
except Exception as e:
print ("Error:{0}".format(e))
运行结果:(查看dom_write.xml文件)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<book price="199"/>
<name>Price c++</name>
</root>
- DOM解析XML文件
#-*- coding=utf-8 -*-
from xml.dom import minidom
with open('dom_write.xml','r',encoding='utf8') as fh:
# parse()获取DOM对象
dom=minidom.parse(fh)
# 获取根节点
root=dom.documentElement
# 节点名称
print(root.nodeName)
# 节点类型:'ELEMENT_NODE',元素节点; 'TEXT_NODE',文本节点; 'ATTRIBUTE_NODE',属性节点
print(root.nodeType)
# 获取某个节点下所有子节点,是个列表
print(root.childNodes)
# 通过dom对象或根元素,再根据标签名获取元素节点,是个列表
book=root.getElementsByTagName('book')[0]
# 获取节点属性
print(book.getAttribute('price'))
# 获取某个元素节点的文本内容,先获取子文本节点,然后通过“data”属性获取文本内容
name=root.getElementsByTagName('name')[0]
name_text_node=name.childNodes[0]
print(name_text_node.data)
# 获取某节点的父节点
print(name.parentNode.nodeName)
运行结果:
root
1
[<DOM Text node "'\n\t'">, <DOM Element: book at 0x2100120>, <DOM Text node "'\n\t'">, <DOM Element: name at 0x2100170>, <DOM Text node "'\n'">]
199
Price c++
root
Python etree模块(爬虫中用的多)
DOM解析XML文件案例(官网https://docs.python.org/2.7/library/xml.etree.elementtree.html)
- XML文件示例
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
内容解析(读取与保持):
>>> import xml.etree.ElementTree as ET
>>> tree = ET.parse('country_data.xml')
>>> root = tree.getroot()
>>> root.tag
'data'
>>> root.attrib
{}
>>> for child in root: #遍历子节点
... print child.tag, child.attrib
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
>>> root[0][1].text #通过索引访问子节点
'2008'
#使用iter访问子节点
>>> for neighbor in root.iter('neighbor'):
... print neighbor.attrib
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
# 通过findall查找标签
>>> for country in root.findall('country'): #findall查找所有子节点标签属性;find查找第一个子节点
... rank = country.find('rank').text #访问内容
... name = country.get('name') #访问元素的属性
... print name, rank
...
Liechtenstein 1
Singapore 4
Panama 68
>>> for rank in root.iter('rank'): #更改子节点的文本内容
... new_rank = int(rank.text) + 1
... rank.text = str(new_rank)
... rank.set('updated', 'yes') #新增子节点的属性
...
>>> tree.write('output.xml')
#删除属性
>>> for country in root.findall('country'):
... rank = int(country.find('rank').text)
... if rank > 50:
... root.remove(country)
...
>>> tree.write('output.xml')
运行结果(省略):
<rank updated="yes">2</rank>
<rank updated="yes">5</rank>
<rank updated="yes">69</rank>
JSON [JavaScript 对象表示法(JavaScript Object Notation)]
-
JSON 是存储和交换文本信息的语法。类似 XML。
-
JSON 比 XML 更小、更快,更易解析。
-
JSON:轻量级的数据交换格式,基于ECMAScript
-
参考学习
-
json格式是一个键值对形式的数据集
- key:字符串
- value:字符串、数字、列表、json
- json使用大括号包裹
- 键值对直接用逗号隔开
-
json和python格式的对应
- string:str/unicode
- number: int,long,float
- 队列:list
- 对象:dict
- 布尔值:布尔值
- array: list,tuple
- null: None
python中的json模块
- json和python对象的转换
- json.dumps():对数据编码,将python对象编码成json字符串
import json
data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ]
json = json.dumps(data,sort_keys=True, indent=4, separators=(',', ': '))
print json #[{"a": 1, "c": 3, "b": 2, "e": 5, "d": 4}]
- json.loads():对数据解码,将已编码的json字符串解码为python对象
import json
jsonData = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
text = json.loads(jsonData)
print text #{u'a': 1, u'c': 3, u'b': 2, u'e': 5, u'd': 4}
- python读取json文件
- json.dump():把内容写入文件
- json.load():