参考:
https://blog.csdn.net/weixin_39274753/article/details/82221859#commentBox
https://www.cnblogs.com/hupeng1234/p/7262371.html
一、ElementTree解析svg,XML
1、元素查找方法find,findall,iter,iterfind
一、match为tag;不含子节点,返回第一个/所有匹配的Element;可查找特定属性attrib[@id="title1"]
find(match)
findall(match)
二、含子节点,返回所有匹配的,不查找特定属性。深度遍历。以当前元素为根节点 创建树迭代器,如果tag不为None,则以tag进行过滤
iter(tag=None)
三、不含子节点,返回所有匹配的。可查找属性。
iterfind(match)
### 导入依赖包
import xml.etree.ElementTree as etree
# 打开文件
tree = etree.ElementTree(file=r'test.svg') # 保证每次操作均为原始model文件
root = tree.getroot() # 获取根元素
# find , findall
# 在test.svg中添加以下内容:
# <g id="switch">
# nihao
# </g>
# findall
# 所有tag,输出列表,for循环列出,不包含嵌套
elems = root.findall('{http://www.w3.org/2000/svg}g[@id="switch"]')
print(elems)
for elem in elems:
print(elem.tag, elem.attrib, elem.text)
# find
# 第一个tag
elem = root.find('{http://www.w3.org/2000/svg}g[@id="switch"]')
print(elem)
print(elem.tag, elem.attrib, elem.text)
output:
findall:
[<Element '{http://www.w3.org/2000/svg}g' at 0x00000000070EE688>, <Element '{http://www.w3.org/2000/svg}g' at 0x00000000070EE868>]
{http://www.w3.org/2000/svg}g {'id': 'switch'}
{http://www.w3.org/2000/svg}g {'id': 'switch'} nihao
find:
<Element '{http://www.w3.org/2000/svg}g' at 0x00000000070EE688>
{http://www.w3.org/2000/svg}g {'id': 'switch'}
# iterfind 找到所有符合条件的tag,循环输出,不包括嵌套标签
for elem in tree.iterfind('{http://www.w3.org/2000/svg}line'):
print(elem.tag, elem.attrib, elem.text)
output:无
# iter 返回所有匹配的标签,包括嵌套的,不能查找属性
elems = tree.iter('{http://www.w3.org/2000/svg}line')
print(elems)
# for elem in elems:
# print(elem.tag, elem.attrib, elem.text)
output:<_elementtree._element_iterator object at 0x000000000709DE08>
2、元素查找方法xpath
# xpath查找
for elem in root.iterfind('{http://www.w3.org/2000/svg}g[@id="switch"]/{http://www.w3.org/2000/svg}text[@class="st4 st8"]'):
print(elem.tag, elem.attrib, elem.text)
output:
{http://www.w3.org/2000/svg}text {'transform': 'matrix(1.0001 0 0 1 28.957 302.7529)', 'class': 'st4 st8'} 1.按此键可开/关空调器。
{http://www.w3.org/2000/svg}text {'transform': 'matrix(1.0001 0 0 1 28.957 313.5518)', 'class': 'st4 st8'} 2.开/关时清除原来设定的定时、睡眠等
{http://www.w3.org/2000/svg}text {'transform': 'matrix(1.0001 0 0 1 28.957 324.2529)', 'class': 'st4 st8'} 功能。
3、特定属性相关操作
elem.attrib 为包含元素属性的字典
elem.keys() 返回元素属性名称列表
elem.items() 返回(name,value)列表
get(key, default=None) 获取属性
set(key, value) 更新/添加 属性
del xxx.attrib[key] 删除对应的属性
for elem in root.iterfind('{http://www.w3.org/2000/svg}g[@id="switch"]/{http://www.w3.org/2000/svg}text[@class="st1 st7 st3"]'):
print(elem.attrib)
print(elem.keys())
print(elem.items())
print(elem.get("class"))
elem.set("class",f"str33")
print(elem.attrib)
del elem.attrib["class"]
print(elem.attrib)
output:
{'transform': 'matrix(1.0001 0 0 1 28.957 292.2505)', 'class': 'st1 st7 st3'}
['transform', 'class']
[('transform', 'matrix(1.0001 0 0 1 28.957 292.2505)'), ('class', 'st1 st7 st3')]
st1 st7 st3
{'transform': 'matrix(1.0001 0 0 1 28.957 292.2505)', 'class': 'str33'}
{'transform': 'matrix(1.0001 0 0 1 28.957 292.2505)'}
4、元素添加与删除
创建元素 | 添加子元素 | 删除元素 |
---|---|---|
ET.Element | append(subelement) | remove(subelement) |
ET.SubElement | extend([subelement1,subelement2]) | del element |
insert(index, element) |
# 删除子元素
elem = root.find('{http://www.w3.org/2000/svg}g[@id="switch"]')
subelem = elem.find('{http://www.w3.org/2000/svg}line[@class="st9"]')
elem.remove(subelem)
g_title1 = root[3]
elem1 = etree.Element("elem1")
elem1.text = 'elem 1'
elem1.tail = '\n'
# g_title1.append(elem1)
# g_title1.extend([elem1])
g_title1.insert(1, elem1)
# etree.dump(root)
# tree = etree.ElementTree(root)
tree.write('test2.svg', encoding="utf-8") # 文件保存
output:
<ns0:g id="switch">
nihao
<elem1>elem 1</elem1>
</ns0:g>
创建xml文件实例
>>> a = ET.Element('elem')
>>> c = ET.SubElement(a, 'child1')
>>> c.text = "some text"
>>> d = ET.SubElement(a, 'child2')
>>> b = ET.Element('elem_b')
>>> root = ET.Element('root')
>>> root.extend((a, b))
>>> tree = ET.ElementTree(root)
>>> tree.write(sys.stdout)
<root><elem><child1>some text</child1><child2 /></elem><elem_b /></root>
ET.dump(root_model) 在终端显示svg文件
二、利用iterparse解析XML流
解决读入xml文件内存过大问题
举例:
1、使用ET.parse方法,先完成树的构建,在遍历查找元素
tree = ET.parse(sys.argv[2]) # 将全部元素载入内存,逐一解析
count = 0
for elem in tree.iter(tag='location'):
if elem.text == 'Zimbabwe':
count += 1
2、使用iterparse方法,废弃掉不需要的元素,循环生成树。只在树被构建时,遍历一次。节约内存和时间
count = 0
for event, elem in ET.iterparse(sys.argv[2]):
if event == 'end':
if elem.tag == 'location' and elem.text == 'Zimbabwe':
count += 1
elem.clear() # 将元素废弃
三、svg部分字体对照列表:
English Name | Localized Name |
---|---|
SimSun | 宋体 |
SimHei | 黑体 |
FangSong_GB2312 | 仿宋_GB2312 |
KaiTi_GB2312 | 楷体_GB2312 |
YouYuan | 幼圆 |
STSong | 华文宋体 |
STZhongsong | 华文中宋 |
STKaiti | 华文楷体 |
STFangsong | 华文仿宋 |
STXihei | 华文细黑 |
STLiti | 华文隶书 |
STXingkai | 华文行楷 |
STXinwei | 华文新魏 |
STHupo | 华文琥珀 |
STCaiyun | 华文彩云 |
FZYaoTi | 方正姚体简体 |
FZShuTi | 方正舒体简体 |
NSimSun | 新宋体 |
LiSu | 隶书 |
附:需要注意的地方
1、svg文本< text >
一个不足之处是 SVG 不执行自动换行。如果文本比允许空间长,则简单地将它切断。多数情况下,创建多行文本需要多个文本元素。可以使用 tspan 元素将文本元素分成几部分,允许每部分有各自的样式。在 text 元素中,空格的处理与 HTML 类似;换行和回车变成空格,而多个空格压缩成单个空格。