文章目录
- 1、Python解析XML方式
- 1.1、DOM方式
- 文件解析
- 创建修改
- 1.2、SAX方式
- 1.3、etree.Element方式
- 文件解析
- 常规解析
- xpath使用
- 命名空间
- 创建修改
- 2、Python操作XML文件
- 2.1、xml文件的创建
- 2.2、节点的操作
XML(EXtensible Markup Language):可扩展标记语言,被设计用来传输和存储数据。
1、Python解析XML方式
Python处理XML文件主要有三种方式:
- XML.DOM模块
DOM:文件对象模型(Document Object Model),在解析XML文件时一次性将 XML 数据读取到内存中解析成一个树,通过对树的操作来操作 XML。
缺点:内存占用率高; - XML.SAX模块
SAX:基于事件驱动的API (simple API for XML ),通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
优点:事件驱动,无需将文件全部读取到内存中; - xml.etree.ElementTree模块
优点:相比于DOM内存占用率低,性能上和SAX相比接近;
Python标准库中,提供了ET的两种实现:
xml.etree.ElementTree(推荐);
xml.etree.cElementTree(弃用);
xml文件A
<?xml version="1.0" encoding="UTF-8"?>
<Model xmlns:a="attribute" xmlns:c="collection" xmlns:o="object">
<c:Tables>
<o:Table Id="o3888">
<a:ObjectID>9C9E4066-4C71-4A3E-8B82-667D001B64F8</a:ObjectID>
<a:Name>缴销申请</a:Name>
<a:Code>JC_ZJK_LC_JXSQ</a:Code>
<a:CreationDate>1589337305</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1593477162</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
<a:Comment>流程缴销申请</a:Comment>
<a:TotalSavingCurrency/>
<a:Description>1.数据源:
2.处理规则:</a:Description>
<c:ExtendedCollections>
<o:ExtendedCollection Id="o4280">
<a:ObjectID>68AD7C9A-04CF-4911-9816-5465B7EB14A3</a:ObjectID>
<a:Name>Related Columns</a:Name>
<a:ExtendedBaseCollection.CollectionName>Related Columns</a:ExtendedBaseCollection.CollectionName>
<a:CreationDate>1619489206</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1619489206</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
</o:ExtendedCollection>
</c:ExtendedCollections>
<c:Columns>
<o:Column Id="o4281">
<a:ObjectID>45FFDDB7-0BE3-4B50-925E-7E76B8B9C315</a:ObjectID>
<a:Name>缴销申请UUID</a:Name>
<a:Code>JXSQUUID</a:Code>
<a:CreationDate>1589337305</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1594004217</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
<a:Comment>缴销申请UUID</a:Comment>
<a:DataType>VARCHAR(37)</a:DataType>
<a:Length>37</a:Length>
<a:Column.Mandatory>1</a:Column.Mandatory>
</o:Column>
<o:Column Id="o4286">
<a:ObjectID>379E9E07-B8A0-49EB-8A1A-C295A9857A0D</a:ObjectID>
<a:Name>受理日期</a:Name>
<a:Code>SLRQ</a:Code>
<a:CreationDate>1589337305</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1593477162</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
<a:Comment>受理日期</a:Comment>
<a:DataType>DATE</a:DataType>
</o:Column>
<o:Column Id="o4294">
<a:ObjectID>7600D929-2493-40B6-A009-BDE4119E23A6</a:ObjectID>
<a:Name>数据同步时间</a:Name>
<a:Code>SJTB_SJ</a:Code>
<a:CreationDate>1589337305</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1593477162</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
<a:Comment>数据同步时间</a:Comment>
<a:DataType>TIMESTAMP(6)</a:DataType>
<a:Length>6</a:Length>
</o:Column>
<o:Column Id="o4302">
<a:ObjectID>3DDCB4AE-165D-4C49-A5EB-C3B4293A3589</a:ObjectID>
<a:Name>数据集成批次号</a:Name>
<a:Code>SJJCPCH</a:Code>
<a:CreationDate>1589337305</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1594004217</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
<a:Comment>数据集成批次号</a:Comment>
<a:DataType>VARCHAR(20)</a:DataType>
<a:Length>20</a:Length>
</o:Column>
</c:Columns>
<c:Keys>
<o:Key Id="o4303">
<a:ObjectID>92207BC1-E331-4969-B43E-6F3231D24203</a:ObjectID>
<a:Name>主键_缴销申请</a:Name>
<a:Code>PK_JC_ZJK_LC_JXSQ</a:Code>
<a:CreationDate>1589337305</a:CreationDate>
<a:Creator>pws</a:Creator>
<a:ModificationDate>1593477162</a:ModificationDate>
<a:Modifier>pws</a:Modifier>
<a:Comment>主键_流程缴销申请</a:Comment>
<c:Key.Columns>
<o:Column Ref="o4281"/>
</c:Key.Columns>
</o:Key>
</c:Keys>
<c:PrimaryKey>
<o:Key Ref="o4303"/>
</c:PrimaryKey>
</o:Table>
</c:Tables>
</Model>
- 结构解析
Xml文件分为 根节点、子节点;节点包含节点名称、节点文本;节点包含属性;属性包含属性名称、属性值;
1.1、DOM方式
python中使用 xml.dom.minidom
来完成对xml文件的解析和操作;
Node.childNodes
Node.nodeName
Node.nodeValue
-
Node.hasAttributes()
说明:返回 True/False; -
Node.hasChildNodes()
说明:返回 True/False;
文档对象
-
Document.documentElement
说明:返回文档的唯一根元素; -
Document.createElement(TagName)
说明:创建并返回具有命名空间的新元素。新创建的节点需要使用方法insertBefore() 或 appendChild()显示的插入到文档中;
文件解析
1)生成dom对象
from xml.dom import minidom
domTree = minidom.parse("OnlineMovie.xml")
rootElement = domTree.documentElement
创建修改
1)创建接口
1.2、SAX方式
暂不介绍;
1.3、etree.Element方式
Python官方文档:https://docs.python.org/zh-cn/3/library/xml.etree.elementtree.html?
• element.tag 说明:返回节点名称;
• element.text 说明:返回节点文本
• element.attrib 说明:返回节点属性,结果为字典类型;
• len(element) 说明:判断元素的子节点数;
• element.get(key) 说明:获取 元素的属性名为 key 的属性值;
文件解析
常规解析
1)生成dom对象
import xml.etree.ElementTree as et
domTree=et.parse("OnlineMovie.xml")
rootElement=domTree.getroot()
2)遍历节点
- 函数实现
def parseXmlElement(element):
print("tag:", element.tag, "-->text:", element.text, "; attrib:", element.attrib)
if len(element) >1:
for x in element:
parseXmlElement(x)
说明:通过递归的方式循环遍历各个节点元素;
element.iter()
element.iter()
element.iter(tag="")
说明:
1)可以按照特定元素名称进行遍历,也可以遍历当前节点的所有子节点;
2)指定元素名称遍历时,只会遍历当前元素,不会遍历其子元素;
for element in rootElement.iter():
print("tag:", element.tag, "-->text:", element.text, "; attrib:", element.attrib)
element.findall(path)
for element in rootElement.findall(path="movie"):
print("tag:", element.tag, "-->text:", element.text, "; attrib:", element.attrib)
说明:element.findall查找文档中具备 特定标签的直接元素;
for element in rootElement.findall(path="movie"):
for x in element.iter():
print("tag:", x.tag, "-->text:", x.text, "; attrib:", x.attrib)
说明:element.iter() 会递归解析当前节点和所有子节点;
element.find(path)
for element in rootElement.find(path="movie"):
print("tag:", element.tag, "-->text:", element.text, "; attrib:", element.attrib)
说明:element.findall查找文档中具备特定标签第一个的子元素;
xpath使用
如下用法等同:
方式A:
rootElement.findall(".//{collection}Views/{object}View") 方式B:
ns = {"o": "object", "c": "collection", "a": "attribute"}rootElement.findall(".//c:Tables/o:Table",namespaces=ns)
- 代码实现
import xml.etree.ElementTree as et
document = et.parse(source="专题模型.pdm")
ns = {"o": "object", "c": "collection", "a": "attribute"}
rootElement = document.getroot()
tableList = rootElement.findall(".//c:Tables/o:Table",namespaces=ns)
viewList = rootElement.findall(".//{collection}Views/{object}View")
objectList = tableList + viewList
for element in objectList:
objId = element.find("{attribute}ObjectID")
Code = element.find("{attribute}Code")
Name = element.find("{attribute}Name")
# print("element.tag={},element.text={}".format(objId.tag,objId.text))
print("element.tag={},element.text={}".format(Code.tag, Code.text))
print("element.tag={},element.text={}".format(Name.tag, Name.text))
命名空间
<Model xmlns:a="attribute" xmlns:c="collection" xmlns:o="object"> 该申明指定了
<a: 表示的命名空间前缀为 attribute;
<c: 表示的命名空间前缀为 collection;
<o:表示的命名空间前缀为 object;在使用 xpath 形式查找特定元素时,可以多级嵌套:
rootElement.findall(".//{object}Column")rootElement.findall(".//{collection}Columns/{object}Column")rootElement.findall(".//{object}Table/{collection}Columns/{object}Column")rootElement.findall(".//{collection}Tables/{object}Table/{collection}Columns/{object}Column")
创建修改
2、Python操作XML文件
2.1、xml文件的创建
2.2、节点的操作