数据交换格式有文本数据交换格式和二进制数据交换格式。文本数据交换格式主要有 CSV 格式、XML 格式、和 JSON 格式。
XML和JSON格式被称为“自描述的”结构化文档,因为这两种格式可以自带描述信息。JSON所用的字节数一般要比XML少,因此JSON也称为“轻量级”的数据交换格式。
CSV文件
CSV(Comma-Separated Values,逗号分隔值)文件是一种简单的文件格式,用于存储表格数据,如电子表格或数据库。CSV文件由一系列的行组成,每行包含若干字段,字段之间由逗号(或其他分隔符,如制表符或分号)分隔。CSV文件通常使用纯文本格式(如UTF-8或ASCII)进行编码,因此它们可以在各种操作系统和应用程序之间轻松交换。
CSV文件示例
以下是一个CSV文件的简单示例:
姓名,年龄,职业
张三,25,工程师
李四,30,医生
王五,28,教师
在这个示例中,第一行是标题行,包含字段名(姓名、年龄、职业)。接下来的每一行都包含与这些字段对应的数据。
特点
- 简单性:CSV文件易于创建和编辑,因为它们只是纯文本文件。
- 可移植性:由于CSV文件是纯文本文件,并且使用标准的分隔符(如逗号),因此它们可以在不同的操作系统和应用程序之间轻松交换。
- 可编辑性:可以使用任何文本编辑器(如Notepad、Sublime Text、VS Code等)打开和编辑CSV文件。
- 支持多种编程语言:大多数编程语言都提供了用于读取和写入CSV文件的库或函数。
CSV文件在数据分析、数据交换和报告生成等场景中非常有用。例如,可以使用CSV文件将Excel表格中的数据导入到Python脚本中进行处理,或者将数据库查询结果导出为CSV文件以供其他人员使用。
XML数据交换格式
XML(Extensible Markup Language,可扩展标记语言)文档结构是一种用于存储和传输数据的标准格式,它通过标签来描述数据的结构和含义。XML文档结构清晰,易于理解和使用,广泛应用于数据交换、配置文件、Web服务等领域。
XML文档结构
XML文档在形式上与HTML很相似,但它有着严格的语法规则,只有严格按照规范编写的XML文档才是有效的文档。XML文档基本架构如下:
(1)声明(可选)
示例如下
<?xml version="1.0" encoding="UTF-8"?>
该示例中定义了XML文件的版本和使用的字符集,此处为1.0版,使用中文UTF-8字符。虽然编码方式是可选的,但通常建议指定,以确保文档在不同环境下的正确解析。
(2)根元素
根元素是整个XML文档的起始元素,包围着其他所有的元素。它是文档的最顶层元素,且只能有一个,开始标签和结束标签必须一致。
(3)子元素
XML文档中的基本构建单元,由开始标签和结束标签组成。开始标签用来标识元素的开始,结束标签用来标识元素的结束。元素可以嵌套其他元素和文本内容,开始标签和结束标签必须一致。如果开始标签和结束标签之间没有内容,可以写成 <from/> ,称为“空标签”。
示例如下
<book>...</book>
(4)属性
属性定义在开始标签中,用来为元素提供额外的信息,由名称和值组成,中间用等号连接。其中属性值必须放置在双引号或单引号之间。一个元素不能有多个相同名字的属性。属性包含在元素的开始标签中。
示例如下
<book id="123">...</book>
(5)命名空间
命名空间是一个URI(统一资源标识符)引用,它用来为XML元素和属性提供唯一的上下文或范围。通过命名空间,即使两个元素具有相同的本地名称(local name),只要它们属于不同的命名空间,它们就会被视为不同的元素。
示例代码如下
<x:employee xmlns:x="http://org1.com/ns">
<!-- org1 的 employee 信息 -->
</x:employee>
<y:employee xmlns:y="http://org2.com/ns">
<!-- org2 的 employee 信息 -->
</y:employee>
(6)限定名
它是由命名空间引出的概念,定义了元素和属性的合法标识符。限定名通常在XML文档中用作特定元素或属性引用。
限定名由两部分组成:前缀(prefix)和本地名称(local name)。前缀是可选的,它用于引用特定的命名空间,而本地名称是元素或属性的实际名称。在上面的(5)的例子中,x:employee
是一个限定名,其中 x
是前缀,employee
是本地名称。如果没有指定前缀(即没有使用命名空间),那么元素或属性的名称就仅仅是其本地名称。然而,在涉及多个命名空间和可能的命名冲突时,使用限定名可以确保每个元素或属性都有唯一的标识。
命名空间和限定名在XML Schema、XSLT、XPath、SOAP等XML相关技术中广泛使用,它们是处理大型和复杂XML文档的关键工具。
(7)文本节点
包含在元素内部的文本内容,这些文本内容会被解析器作为数据的一部分进行解析。
(8)注释
用来对XML文档进行注释,不会被解析器解析。注释以<!--
开始,以-->
结束。
以下是一个XML文档示例
<?xml version="1.0" encoding="UTF-8"?>
<!-- 这是一个书店的XML表示 -->
<bookstore>
<book>
<title lang="en">C++ Programming Language</title>
<author>Bjarne Stroustrup</author>
<year>1998</year>
<price>98.0</price>
</book>
<book>
<title lang="en">TCP/IP Illustrated</title>
<author>Richard Stevens</author>
<year>1996</year>
<price>56.0</price>
</book>
</bookstore>
解析XML文档
XML文档操作有“读”与“写”两种,读入XML文档并分析的过程称为“解析”。解析XML文档有SAX和DOM两种流行的模式。
SAX(Simple API for XML)是一种基于事件驱动的解析模式。解析XML文档时,程序从上到下读取XML文档,遇到开始标签、结束标签和属性等,就会触发相应的事件。但是这种解析XML文档的方式只能读取XML文档,不能写入XML文档,它的优点是解析速度快,所以当只需要读取的XML文档进行解析,推荐用这种方式。
DOM(Document Object Model)将XML文档作为一个树状结构进行分析,获取节点的内容以及相关属性,或是新增、删除和修改节点的内容。XML解析器在加载XML文档后,DOM模式将XML文件的元素视为一个树状结构的节点,一次性读入内存。如果文档比较大,解析速度就会变慢。
下面通过一个示例代码来说明
首先新建Notes.xml文档,输入下面代码
<?xml version="1.0" encoding="UTF-8"?>
<Notes>
<Note id="1">
<CDate>2024-3-21</CDate>
<Content>发布CSDN文章1</Content>
<UserID>tony</UserID>
</Note>
<Note id="2">
<CDate>2024-3-22</CDate>
<Content>发布CSDN文章2</Content>
<UserID>tony</UserID>
</Note>
<Note id="3">
<CDate>2024-3-23</CDate>
<Content>发布CSDN文章3</Content>
<UserID>tony</UserID>
</Note>
<Note id="4">
<CDate>2024-3-24</CDate>
<Content>发布CSDN文章4</Content>
<UserID>tony</UserID>
</Note>
<Note id="5">
<CDate>2024-3-25</CDate>
<Content>发布CSDN文章5</Content>
<UserID>tony</UserID>
</Note>
</Notes>
再在.py文件中输入下面代码
import xml.etree.ElementTree as ET
tree = ET.parse('Notes.xml') # 创建XML文档树
print(type(tree)) # xml.etree.ElementTree.ElementTree
root = tree.getroot() # root是根元素
print(type(root)) # xml.etree.ElementTree.Element
print(root.tag) # Notes
for index,child in enumerate(root):
print(f'第{index}个{child.tag}元素,属性:{child.attrib}')
for i,child_child in enumerate(child):
print(' 标签:{0},内容:{1}'.format(child_child.tag,child_child.text))
注意:代码第三行中我的路径是采用相对路径,且新建的文件和我的 .py 文件在同一个目录下。
代码运行结果
<class 'xml.etree.ElementTree.ElementTree'>
<class 'xml.etree.ElementTree.Element'>
Notes
第0个Note元素,属性:{'id': '1'}
标签:CDate,内容:2024-3-21
标签:Content,内容:发布CSDN文章1
标签:UserID,内容:tony
第1个Note元素,属性:{'id': '2'}
标签:CDate,内容:2024-3-22
标签:Content,内容:发布CSDN文章2
标签:UserID,内容:tony
第2个Note元素,属性:{'id': '3'}
标签:CDate,内容:2024-3-23
标签:Content,内容:发布CSDN文章3
标签:UserID,内容:tony
第3个Note元素,属性:{'id': '4'}
标签:CDate,内容:2024-3-24
标签:Content,内容:发布CSDN文章4
标签:UserID,内容:tony
第4个Note元素,属性:{'id': '5'}
标签:CDate,内容:2024-3-25
标签:Content,内容:发布CSDN文章5
标签:UserID,内容:tony
Process finished with exit code 0
XPath
XPath(XML Path Language)是一种在XML文档中查找信息的语言。如果说XML是数据库,那么XPath就是SQL。它使用路径表达式来选取XML文档中的节点或节点集。XPath被设计用来从XML文档中抽取数据,它也可以用于HTML文档,因为HTML可以看作是XML的一个子集。XPath通过元素的层级关系来定位节点,这些层级关系可以是父子关系、兄弟关系或祖先-后代关系。它将XML中的所有元素、属性和文本都看作节点,它没有父节点,根元素就是根节点、属性就是属性节点、文本就是文本节点,除根节点外,其他节点都有一个父节点,零或多个子节点和兄弟节点。
XPath的核心概念包括:
-
节点(Nodes):在XPath中,XML文档被视作一个节点树,其中包含了不同类型的节点,如元素节点、属性节点、文本节点等。
-
路径表达式(Path Expressions):XPath使用路径表达式来选择节点。这些表达式类似于文件系统中的路径,它们描述了从文档中的某个点到达另一个点的路径。
-
轴(Axes):XPath定义了多种轴,以表示节点与节点之间的关系。例如,
child
轴表示父子关系,sibling
轴表示兄弟关系,ancestor
轴表示祖先关系等。 -
谓词(Predicates):谓词用于进一步筛选通过路径表达式选取的节点集。它们被附加在路径表达式的末尾,并包含在一对方括号内。谓词通常使用条件表达式来过滤节点。
-
函数(Functions):XPath提供了丰富的函数库,这些函数可以对选取的节点集执行各种操作,如字符串操作、数值操作、日期和时间操作等。
XPath的一些基本用法包括:
- 选取节点:使用元素名、属性名或路径表达式来选取XML文档中的节点。
- 选取子节点:使用斜杠(/)来选取子节点。
- 选取属性:使用@符号来选取属性。
- 选取多个节点:使用逗号(,)分隔不同的路径表达式,可以同时选取多个节点。
- 使用通配符:
*
可以代表任何元素节点,@*
可以代表任何属性节点。
XPath广泛应用于各种编程语言和工具中,以实现对XML或HTML文档的解析和数据处理。例如,在Web开发中,XPath常用于JavaScript(通过DOM API)和服务器端语言(如PHP、Python等)中,以提取网页中的数据。在数据库和XML处理软件中,XPath也扮演着重要角色。
XPath表达式
表达式 | 说明 |
---|---|
nodename | 选择nodename子节点 |
. | 选择当前节点 |
/ | 路径指示符,相当于路径分隔符 |
.. | 选择父节点 |
// | 所有后代节点(包括子节点、孙节点等) |
[@attrib] | 选择指定属性的所有节点 |
[@attrib='value'] | 选择指定属性等于value的所有节点 |
[position] | 指定位置,位置从1开始,最后一个可以使用last()获取 |
使用XPath
上面的示例是从根元素开始遍历整个XML文档,实际可能需要查找某些特殊的元素或某些特殊的属性,此时需要用到 xml.etree.ElementTree.Element 的相关find方法,还要结合XPath路径来找。
方法名 | 说明 |
---|---|
find(match,namespaces=None) | 查找匹配的第一个子元素。match可以是标签名或XPath,返回元素对象或None。namespaces是指定命名空间,如果namespaces非空,那么查找会在指定的命名空间的标签中进行。 |
fildall(match,namespaces=None) | 查找所有匹配的子元素,参数与find()方法相同,返回值是符合条件的元素列表。 |
findtext(match,default=None,namespaces=None) | 查找匹配的第一个子元素的文本,如果未找到元素,则返回默认。default是默认值。 |
示例代码如下
import xml.etree.ElementTree as ET
tree = ET.parse('Notes.xml') # 创建XML文档树
root = tree.getroot() # root是根元素
node = root.find("./Note") # 当前节点下的第一个Note子节点
print(node.tag,node.attrib)
node = root.find("./Note/CDate") # Note子节点下的第一个CDate节点
print(node.text)
node = root.find("./Note/CDate/..") # Note节点
print(node.tag,node.attrib)
node = root.find(".//CDate") # 当前节点查找所有后代节点中第一个CDate节点
print(node.text)
node = root.find("./Note[@id]") # 具有id属性的Note节点
print(node.tag,node.attrib)
node = root.find("./Note[@id='2']") # id属性等于 2 的Note节点
print(node.tag,node.attrib)
node = root.find("./Note[last()]") # 最后一个Note节点
print(node.tag,node.attrib)
node = root.find("./Note[last()-2]") # 倒数第三个Note节点
print(node.tag,node.attrib)
代码运行结果
Note {'id': '1'}
2024-3-21
Note {'id': '1'}
2024-3-21
Note {'id': '1'}
Note {'id': '2'}
Note {'id': '5'}
Note {'id': '3'}
Process finished with exit code 0
JSON数据交换格式
JSON文档格式
由于 web 和移动平台开发对流量的要求是尽可能少,对速度的要求是尽可能快,使用JSON可以易于阅读和编写,同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。JSON采用完全独立于语言的文本格式,但是使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使得轻量级的数据交换格式 JSON 就成为理想的数据交换格式。
构成 JSON 文档的两种结构为对象(object)和数组(array)。对象是“名称:值”对集合,它类似于 python 中 Map 类型,而数组是一连串元素的集合。
JSON对象
JSON 对象(object)是一个无序的“名称/值”对集合,一个对象以“ { ”开始,以“ } ”结束。每个“名称”后跟一个“:”,“名称:值”对之间使用逗号“,”分隔,“名称”是字符串类型,“值”可以是任何合法的JSON类型。
下面是一个JSON对象的例子:
# 示例一
{
"name":"abc.html",
"size":100,
"saved":true
}
# 示例二
{
"name": "John Doe",
"age": 30,
"isStudent": false,
"courses": ["Math", "Science"],
"address": {
"street": "1234 Elm St",
"city": "Somewhere"
}
}
JSON数组
JSON 数组是值的有序集合,以“ [ ”开始,以“ ] ”结束,。值之间使用“,”分隔。下面是一个JSON数组的例子:
# 示例一
["html","css","JavaScript"]
# 示例二
[
{
"id": 1,
"name": "Apple",
"price": 0.99
},
{
"id": 2,
"name": "Banana",
"price": 0.50
},
{
"id": 3,
"name": "Cherry",
"price": 2.50,
"inStock": false
}
]
JSON中的值可以是双引号括起来的字符串、数字、true、false、对象或数组,而且这些结构可以嵌套。编写时需要注意:字符串类型的值必须用双引号(")而不是单引号(')括起来,数组和对象的最后一个成员后面不能有多余的逗号,JSON的值不能是函数、日期或undefined。
JSON 数据编码格式
在Python程序中要想将Python数据进行网络传输和存储,可以将Python数据转换为JSON格式再进行传输和存储,这个过程称为“编码(encode)”。JSON数据在网络传输或保存到磁盘中,推荐使用JSON对象。
Python提供的内置模块json可以帮助实现JSON的编码和解码,JSON编码使用dumps()和dump()函数,dumps()函数将编码的结果以字符串的形式返回,dump()方法将编码的结果保存到文件对象(类似流)中。
Python | JSON |
---|---|
字典 | 对象 |
列表、元组 | 数组 |
字符串 | 字符串 |
整数、浮点数等数字类型 | 数字 |
True | true |
False | false |
None | null |
示例代码如下
import json
# 准备数据
py_dict = {"name":"Tom","age":18,"sex":True} # 创建字典对象
py_list = [1,3] # 创建列表对象
py_tuple = ("A","B","C") # 创建元组对象
# 添加列表到字典中
py_dict['a'] = py_list
# 这行代码向 py_dict 字典中添加了一个新的键值对,其中键是字符串 'a',值是列表 py_list。
# 这是有效的,因为字典可以存储任何类型的对象作为其值。
# 添加元组到字典中
py_dict['b'] = py_tuple
# 创建一个新的键值对在 py_dict 中,键是字符串 'b',值是元组 py_tuple。
# 这是有效的,因为字典的值可以是任何类型。
print(py_dict)
print(type(py_dict))
#编码过程
json_obj = json.dumps(py_dict)
print(json_obj)
print(type(json_obj))
#编码过程
json_obj1 = json.dumps(py_dict,indent=4)
# 漂亮的格式化字符串后输出
print(json_obj1)
# 写入JSON数据到data1.json文件
with open("data1.json","w") as f:
json.dump(py_dict,f)
# 写入JSON数据到data2.json文件
with open("data2.json","w") as f:
json.dump(py_dict,f,indent=4)
代码运行结果
控制台输出如下
{'name': 'Tom', 'age': 18, 'sex': True, 'a': [1, 3], 'b': ('A', 'B', 'C')}
<class 'dict'>
{"name": "Tom", "age": 18, "sex": true, "a": [1, 3], "b": ["A", "B", "C"]}
<class 'str'>
{
"name": "Tom",
"age": 18,
"sex": true,
"a": [
1,
3
],
"b": [
"A",
"B",
"C"
]
}
Process finished with exit code 0
data1.json输出如下
{"name": "Tom", "age": 18, "sex": true, "a": [1, 3], "b": ["A", "B", "C"]}
data2.json输出如下
{
"name": "Tom",
"age": 18,
"sex": true,
"a": [
1,
3
],
"b": [
"A",
"B",
"C"
]
}
JSON数据解码
编码的相反过程为“解码(decode)”,即将JSON数据转换为Python数据。从网络中接收或从磁盘中读取JSON数据时,需要解码为Python数据。
json模块提供的解码函数是loads()和load(),loads()函数将JSON字符串数据进行解码,返回Python数据,load()函数读取文件或流,对其中的JSON进行解码,返回结果为Python数据。
示例代码如下
import json
# 准备数据:表示JSON对象的字符串
json_obj = r'{"name": "Tom", "age": 18, "sex": true, "a": [1, 3], "b": ["A", "B", "C"]}'
# 对JSON对象进行解码
py_dict = json.loads(json_obj)
print(type(py_dict))
print(py_dict['name'])
print(py_dict['age'])
print(py_dict['sex'])
# 取出列表对象
py_lista = py_dict['a']
print(py_lista)
# 取出列表对象
py_listb = py_dict['b']
print(py_listb)
# 读取JSONdata2.json文件中的JSON数据解码并返回Python对象
with open('data2.json','r') as f:
data = json.load(f)
print(data)
print(type(data))
代码运行结果
<class 'dict'>
Tom
18
True
[1, 3]
['A', 'B', 'C']
{'name': 'Tom', 'age': 18, 'sex': True, 'a': [1, 3], 'b': ['A', 'B', 'C']}
<class 'dict'>
Process finished with exit code 0
参考书籍:《python从小白到大牛》(第2版)关东升 编著
文章创作不易,本文10000+字,为了大家能理解,写的很详细,这也让我花了很多时间。最后,如果觉得本文对大家有帮助的话,还请给我点个赞和关注,谢谢大家!!!
标签:XML,元素,py,JSON,文档,格式,易懂,数据交换,节点 From: https://blog.csdn.net/2302_76708905/article/details/140110062