诸神缄默不语-个人技术博文与视频目录
文章目录
- 1. XML格式简介
- 2. 格式化XML文件的工具
- 3. Python处理XML:xml库
- 1. xml.etree.\(c\)ElementTree
- 2. xml.dom.minidom
- 4. 本文撰写过程中参考的其他网络资料
1. XML格式简介
可扩展标记语言 (Extensible Markup Language, XML)
总之也是一种用来定义数据规范的纯文本格式。呃但是也可以拿来按这种规范来存储数据。
大小写敏感。
示例:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="osg.AndroidExample"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8"></uses-sdk>
<uses-feature android:glEsVersion="0x00020000"/> <!-- OpenGL min requierements (2.0) -->
<uses-permission android:name="android.permission.INTERNET"/>
<application android:label="@string/app_name" android:icon="@drawable/osg">
<activity android:name=".osgViewer"
android:label="@string/app_name" android:screenOrientation="landscape"> <!-- Force screen to landscape -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
格式上有点类似于HTML,由XML元素组成,每个XML元素包括一个开始标记(<factor_name>
),一个结束标记(</factor_name>
)以及两个标记之间的内容。
有且只有一个根元素。就是紧接着声明后面建立的第一个元素,其他元素都是这个根元素的子元素,根元素完全包括文档中其他所有的元素。根元素的起始标记要放在所有其他元素的起始标记之前;根元素的结束标记要放在所有其他元素的结束标记之后。
XML声明是XML文档的第一句,其格式如下:
<?xml version="1.0" encoding="utf-8"?>
所有属性值必须加引号(可以是单引号,也可以是双引号,建议使用双引号)。
2. 格式化XML文件的工具
在线格式化:https://c.runoob.com/front-end/710/
也可以用VSCode上的这个插件:
安装后打开XML文件时,在窗口中右键选择“Format Document”就能格式化XML文件。
3. Python处理XML:xml库
本节各小节用的原XML文件都大致长这样:
实际上是从C:\Users\user_name\AppData\Roaming\Tencent\WeChat\3\host里面随便抓的一个XML文件。
1. xml.etree.(c)ElementTree
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
cElementTree是用C写的更快的实现。接口用法看起来都是一样的。
模块的类:
ElementTree:是一个层级式的XML元素。
ElementTree.Element(tag)是一个XML元素。
模块函数:
ElementTree.SubElement(parent,tag)
:为XML元素增加一个子元素,返回这个子元素(一个Element实例)。
ElementTree.parse(xml_file_path)
:解析一个XML文档为ElementTree对象
ElementTree对象的函数:
getroot()
:返回根元素(一个Element实例)
write(file_or_filename,encoding)
Element对象的属性:
tag
text
Element对象的方法:
findall(tag)
:返回当前Element对象的指定tag的所有子元素(一个Element的迭代器)
find(tag)
:返回当前Element对象的指定tag的第一个子元素(一个Element对象)
append(subelement:Element)
:给当前Element对象增加一个子元素(一个Element对象)
示例代码:
按照指定tag查询子元素的子元素的第一个子元素的text的代码示例:
import xml.etree.ElementTree as ET
tree = ET.parse(r'trys\example.xml')
root=tree.getroot()
for function in root.findall('function'):
for domainlist in function.findall('domainlist'):
domain=domainlist.find('domain')
print(domain.text)
break
break
输出:long.weixin.qq.com
↑注意在这里我们可以发现xml对象中,每一层只能检索(不管是用find
还是findall
)当前对象的属性,就是说如果你跨级检索就检索不到。
在现成的XML文件中增加一个子元素的代码示例:
import xml.etree.ElementTree as ET
tree = ET.parse(r"trys\example.xml")
root = tree.getroot()
book = ET.Element("book")
title = ET.SubElement(book, "title")
title.text = "机器学习"
root.append(book)
tree.write(r"trys\example2.xml", encoding="utf-8")
输出XML文件最后的内容示例(注意这是我用XML插件格式化后的效果):
2. xml.dom.minidom
官方文档:https://docs.python.org/3/library/xml.dom.minidom.html
模块类:
Document
Element
Node
Text
模块函数:
parseString(string)
:将XML字符串转化为xml.DOM(Document对象)
Document对象的属性:
documentElement:获取DOM的根元素
Document对象的函数:
writexml(file_writer:TextIOWrapper,indent:str,addindent:str,newl:str)
:将DOM写入文本文件,所以此处的TextIOWrapper需要是可写的。
Element对象的属性:
childNodes:理论上是返回子节点列表(xml.dom.minicompat.NodeList对象),每个元素是一个Node,但是事实上会直接实例化成具体的Node分类(如示例中的Text对象)。这个好像只在没有子元素的元素里才有用,可以从其第一个元素里获得data属性,这个就是Element对象的文本。具体的可以见示例代码
Element对象的函数:
getElementsByTagName(tag)
:获取当前Element对象所有指定tag的子元素,返回一个xml.dom.minicompat.NodeList对象,这个对象是可以用索引直接获取每个元素(Element实例)的
getAttribute(attname)
:根据属性名获取当前Element的属性值
Text对象的属性:
data:文字
nodeType:3(Node.TEXT_NODE的值)
Node对象的属性:
示例代码,简单版:
from xml.dom.minidom import parseString
xml_str=open(r"trys\example.xml",encoding="utf-8").read()
doc=parseString(xml_str)
functionlist=doc.documentElement
function_iterator=functionlist.getElementsByTagName("function")
function1=function_iterator[0] #xml.dom.minidom.Element对象
print(function1.getAttribute("name")) #输出:basic
domain_lists=function1.getElementsByTagName("domainlist")
domain_list1=domain_lists[0]
domains=domain_list1.getElementsByTagName("domain")
domain1=domains[0]
childnodes=domain1.childNodes #xml.dom.minicompat.NodeList对象
the_childnode=childnodes[0] #xml.dom.minidom.Text对象
print(the_childnode.nodeType) #输出:3
print(the_childnode.data) #输出:long.weixin.qq.com
在真实项目中的使用代码可以参考我的另一篇博文:如何用Python 3调用ArXiv API查询ArXiv论文元数据
4. 本文撰写过程中参考的其他网络资料
- 可扩展标记语言_百度百科
- XML到底是干什么的? - 知乎