GVKun编程网logo

如何使用Python ElementTree提取xml属性(python elementtree解析xml)

9

对于想了解如何使用PythonElementTree提取xml属性的读者,本文将是一篇不可错过的文章,我们将详细介绍pythonelementtree解析xml,并且为您提供关于pythonXMLEl

对于想了解如何使用Python ElementTree提取xml属性的读者,本文将是一篇不可错过的文章,我们将详细介绍python elementtree解析xml,并且为您提供关于python XML ElementTree的增删改查、python xml.etree.ElementTree遍历xml所有节点实例详解、python xml解析之 xml.etree.ElementTree、Python XML解析之ElementTree的有价值信息。

本文目录一览:

如何使用Python ElementTree提取xml属性(python elementtree解析xml)

如何使用Python ElementTree提取xml属性(python elementtree解析xml)

对于:

<foo> <bar key="value">text</bar></foo>

我如何获得“价值”?

xml.findtext("./bar[@key]")

引发错误。

答案1

小编典典

这将找到名为的元素的第一个实例,bar并返回该属性的值key

In [52]: import xml.etree.ElementTree as ETIn [53]: xml=ET.fromstring(contents)In [54]: xml.find(''./bar'').attrib[''key'']Out[54]: ''value''

python XML ElementTree的增删改查

python XML ElementTree的增删改查

import xml.etree.ElementTree as ET

"""
    ElementTree.write()       将构建的XML文档写入(更新)文件。
    Element.set(key, value)   添加和修改属性
    Element.text = ''''         直接改变字段内容
    Element.remove(Element)   删除Element节点
    Element.append(Element)   为当前的Elment对象添加子对象
    ET.SubElement(Element,tag)创建子节点 
"""

#  增加自动缩进换行
def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i
            

#------------新增XML----------

#创建根节点
a = ET.Element("student")
#创建子节点,并添加属性
b = ET.SubElement(a,"name")
b.attrib = {"NO.":"001"}
#添加数据
b.text = "张三"
#创建elementtree对象,写文件
indent(a,0)
tree = ET.ElementTree(a)
tree.write("writeXml.xml",encoding="utf-8")

#----------编辑XML--------
# 读取待修改文件
updateTree = ET.parse("writeXml.xml")
root = updateTree.getroot()

# --新增--

# 创建新节点并添加为root的子节点
newnode = ET.Element("name")
newnode.attrib = {"NO.":"003"}
newnode.text = "张三水"
root.append(newnode)

#---修改---

sub1 = root.findall("name")[2]
# --修改节点的属性
sub1.set("NO.","100")
# --修改节点内文本
sub1.text="陈真"

#----删除---

#--删除标签内文本
sub1.text = ""
#--删除标签的属性
del sub1.attrib["NO."]
#--删除一个节点
root.remove(sub1)


# 写回原文件
indent(root,0)
updateTree.write("writeXml.xml",encoding="utf-8", xml_declaration=True)

XML操作封装

def change_node_properties(nodelist, kv_map, is_delete=False):
    ''''''修改/增加 /删除 节点的属性及属性值
       nodelist: 节点列表
       kv_map:属性及属性值map''''''
    for node in nodelist:
        for key in kv_map:
            if is_delete:
                if key in node.attrib:
                    del node.attrib[key]
            else:
                node.set(key, kv_map.get(key))

def change_node_text(nodelist, text, is_add=False, is_delete=False):
    ''''''改变/增加/删除一个节点的文本内容
       nodelist:节点列表
       text : 更新后的文本''''''
    for node in nodelist:
        if is_add:
            node.text += text
        elif is_delete:
            node.text = ""
        else:
            node.text = text

def create_childnode(node,tag, property_map, content):
    ''''''新造一个子节点
       node:节点
       tag:子节点标签
       property_map:属性及属性值map
       content: 节点闭合标签里的文本内容
     ''''''
    element = ET.Element(tag, property_map)
    element.text = content
    node.append(element)

def del_node_by_tagkeyvalue(node, tag, kv_map):
    ''''''通过属性及属性值定位一个节点,并删除之
       node: 父节点
       tag:子节点标签
       kv_map: 属性及属性值列表''''''
    for child in node:
        if child.tag == tag and child.attrib==kv_map:
            node.remove(child)

 

python xml.etree.ElementTree遍历xml所有节点实例详解

python xml.etree.ElementTree遍历xml所有节点实例详解

python xml.etree.ElementTree遍历xml所有节点

XML文件内容:

<students> 
  <student name='刘备' sex='男' age='35'/> 
  <student name='吕布' sex='男' age='38'/> 
  <student name='貂蝉' sex='女' age='22'/> 
</students> 

代码:


#-*- coding: UTF-8 -*-  
# 从文件中读取数据 
import xml.etree.ElementTree as ET 
 
#全局唯一标识 
unique_id = 1 
 
#遍历所有的节点 
def walkData(root_node,level,result_list): 
  global unique_id 
  temp_list =[unique_id,root_node.tag,root_node.attrib] 
  result_list.append(temp_list) 
  unique_id += 1 
   
  #遍历每个子节点 
  children_node = root_node.getchildren() 
  if len(children_node) == 0: 
    return 
  for child in children_node: 
    walkData(child,level + 1,result_list) 
  return 
 
#获得原始数据 
#out: 
#[ 
#  #ID,Level,Attr Map 
#  [1,1,{'ID':1,'Name':'test1'}],#  [2,'Name':'test2'}],#] 
def getXmlData(file_name): 
  level = 1 #节点的深度从1开始 
  result_list = [] 
  root = ET.parse(file_name).getroot() 
  walkData(root,result_list) 
 
  return result_list 
 
if __name__ == '__main__': 
  file_name = 'test.xml' 
  R = getXmlData(file_name) 
  for x in R: 
    print x 
  pass 

输出结果:


[1,'students',{}] 
[2,2,'student',{'age': '35','name': u'\u5218\u5907','sex': u'\u7537'}] 
[3,{'age': '38','name': u'\u5415\u5e03','sex': u'\u7537'}] 
[4,{'age': '22','name': u'\u8c82\u8749','sex': u'\u5973'}] 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

python xml解析之 xml.etree.ElementTree

python xml解析之 xml.etree.ElementTree

import xml.etree.ElementTree as tree
import io


xml = ''''''<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
''''''
parse = tree.fromstring(xml) #type:tree.Element #根节点
for e in parse: #遍历
    print(e.tag) # 节点名称
    print(e.attrib.get(''name''))#节点属性
result = parse.findall(''country'') # 只能找到子节点 第一层
print(result) #[<Element ''country'' at 0x0000000001DDE7C8>, <Element ''country'' at 0x000000000291F908>, <Element ''country'' at 0x000000000291FA98>]

print([e for e in parse.iter(''rank'') if e.attrib.get(''updated'') == ''yes'']) #递归遍历所有

#父节点 parse 添加子节点
print(tree.SubElement(parse, ''test'', attrib={''name'': ''ceshi''})) #工厂方式添加子节点

print(tree.tostring(parse).decode(''utf-8'')) #输出xml文档

 

Python XML解析之ElementTree

Python XML解析之ElementTree

参考网址:
http://www.runoob.com/python/python-xml.html
https://docs.python.org/2/library/xml.etree.elementtree.html
菜鸟教程提供了基本的XML编程接口DOM、SAX,以及轻量级ElementTree的简易概念说明和一些示例。DOM是一种跨语言的XML解析机制,通过将整个XML在内存中解析为一个树来操作,ElementTree未做太多介绍,你可以到官网网址查看其详细的方法释义。
ElementTree是Python中最快捷的XML解析方式,可以看做一个轻量级的DOM,本文主要讲ElementTree,ElementTree在解析XML时非常方便,DOM比较笨重但是功能齐全,例如ElementTree处理XML注释时就很不方便(详见https://bugs.python.org/issue8277),此时用DOM比较好。

API名称:

from xml.etree import ElementTree as ET

概念定义:

<country name="Liechtenstein">
    <rank>1</rank>
    <year>2008</year>
    <gdppc>141100</gdppc>
    <neighbor name="Austria" direction="E"/>
    <neighbor name="Switzerland" direction="W"/>
</country>
我们把<country>xxx</contry>这种结构称为一个element,country称作element的tag,<></>之间的内容称作element的text或data,<>中的name称作element的attrib,而整个XML树被称作ElementTree。
element是一个名为xml.etree.ElementTree.Element的类,其描述为:
class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
此类的所有属性和方法查看:
https://docs.python.org/2/library/xml.etree.elementtree.html#element-objects

方法释义:

读取XML数据:
--读取XML文件
import xml.etree.ElementTree as ET
tree = ET.parse(''country_data.xml'')
root = tree.getroot()
--读取XML字符串
root = ET.fromstring(country_data_as_string)
--获取element object的四大属性tag、text、attrib以及tail
 root.tag #root element的tag
 root.text #root element的text
 root.attrib #root element本身的attrib,dict格式的
 root.tail #root element的tag结束到下一个tag之间的text
 --通过DICT逻辑获取树形结构的text,表示第一个child的第二个child element的text
 root[0][1].text

element object的方法:

Element.iter(tag) --遍历当前element树所有子节点的element(无论是子节点还是子节点的子节点),找到符合指定tag名的所有element,如果tag为空则遍历当前element树,返回所有节点element(包含当前父节点)。2.7和3.2之前的版本无此方法,可以用getiterator()代替。
Element.findall(tag) --遍历当前节点的直接子节点,找到符合指定tag名的element,返回由element组成的list
Element.find(tag) --遍历当前节点的直接子节点,找到符合指定tag名的第一个element
Element.get(key) --在当前element中获取符合指定attrib名的value
...其他方法参考官网

修改XML内容:

ElementTree.write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")  --将之前的修改写入XML
Element.set(key,value) --设置element attrib
Element.append(subelement) --新增一个子element,extends(subelements)是3.2的新增用法,输入参数必须是一个element序列
Element.remove(subelement) --删除指定tag的element
示例:
>>> 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'')

处理含有Namespaces的XML文件:

--有一个如下的XML字符串:
<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
        xmlns="http://people.example.com">
    <actor>
        <name>John Cleese</name>
        <fictional:character>Lancelot</fictional:character>
        <fictional:character>Archie Leach</fictional:character>
    </actor>
    <actor>
        <name>Eric Idle</name>
        <fictional:character>Sir Robin</fictional:character>
        <fictional:character>Gunther</fictional:character>
        <fictional:character>Commander Clement</fictional:character>
    </actor>
</actors>
其中包含fictional和default两个命名空间,这意味fictional:xxx格式的tags、attributes都会被自动扩展为{uri}xxx格式。而如果还定义了默认命名空间xmlns,那么所有无前缀的tags也会被扩展为{url}xxx格式。
有两种将此类XML处理为普通格式的方法:
方法一:在匹配时直接手动加上{uri}前缀
root = fromstring(xml_text)
for actor in root.findall(''{http://people.example.com}actor''):
    name = actor.find(''{http://people.example.com}name'')
    print name.text
    for char in actor.findall(''{http://characters.example.com}character''):
        print '' |-->'', char.text
方法二:创建自己的namespace别名(其实只是在ns uri很长时可以少写点,实质并没有效率提升)
ns = {''real_person'': ''http://people.example.com'',''role'': ''http://characters.example.com''}
for actor in root.findall(''real_person:actor'', ns):
    name = actor.find(''real_person:name'', ns)
    print name.text
    for char in actor.findall(''role:character'', ns):
        print '' |-->'', char.text
--两种方式的输出结果都是:
John Cleese
 |--> Lancelot
 |--> Archie Leach
Eric Idle
 |--> Sir Robin
 |--> Gunther
 |--> Commander Clement

一个比较proxool.xml文件的示例代码:

# -*- coding:utf-8 -*-
# 用于进行配置文件的差异比较,2.7和3.2之前element没有iter()的遍历方法可以用getiterator()代替
import sys
from xml.etree import ElementTree as ET
from xml.dom import minidom
# 定义新旧XML文件分别为输入参数1和2
old_file = sys.argv[1]
new_file = sys.argv[2]
# 定义将新增tag加入旧XML文件的方法
def modify_xml(old_file,new_file):
    if not new_file:
        sys.exit(0)
    tree_old = ET.parse(old_file) # 解析出整个ElementTree
    tree_new = ET.parse(new_file)
    global root # 定义全局变量root,只解析一次方便prettify_xml方法调用
    root = tree_old.getroot()
    root_old = tree_old.getroot().find("proxool")  # 定位旧XML父节点proxool
    root_new = tree_new.getroot().find("proxool")
    old_dict = {} # 定义旧XML文件的tag/text字典
    new_dict = {}
    for e in root_old.getiterator():  # 遍历proxool树的所有节点element,包含其作为父节点的自身
        # text为空时不能使用replace方法,因此加上判断;if e.text不能排除空字符'' '',只能过滤none和''''因此加上strip()过滤
        if e.text and e.tag != ''proxool'' and e.text.strip() != '''':
            old_dict[e.tag] = e.text.replace("\n", "").replace("\t", "")
    for e in root_new.getiterator():
        if e.text and e.tag != ''proxool'' and e.text.strip() != '''':
            new_dict[e.tag] = e.text.replace("\n", "").replace("\t", "")
    # 至此新旧XML文件的tag/text已经作为字典的元素存在了old_dict和new_dict中,只要比较这两个字典就可以拿到新增tag
    for tag,text in new_dict.items():
        if not old_dict.get(tag):  # 当旧XML中找不到对应的tag时,进行tag新增操作
            new_tag = ET.Element(tag) # 构造一个element
            new_tag.text = text # 设置此element的text
            root_old.append(new_tag) #将此element加入root_old节点下作为其子节点
        else:
            pass # 只为美观,可以不写else
    tree_old.write(old_file + "_fixed",encoding="UTF-8") # 最后将append的整个ElementTree写入旧XML_fixed文件中,这样注释会丢失
# 新写入的XML项不是那么美观,再美化一下(发现结果更难看了,有待优化)
def prettify_xml(filename):
    strTree = ET.tostring(root) #使用全局变量root
    new_strTree = minidom.parseString(strTree).toprettyxml()
    with open(filename,''w'') as output:
        output.write(new_strTree)
# 执行函数
modify_xml(old_file,new_file)
prettify_xml(old_file + "_fixed")  

# Ps:后来发现使用ElementTree解析的XML文件很难美化,且不能处理注释,所以转用minidom处理XML文件了,详见《Python XML解析之DOM》

我们今天的关于如何使用Python ElementTree提取xml属性python elementtree解析xml的分享已经告一段落,感谢您的关注,如果您想了解更多关于python XML ElementTree的增删改查、python xml.etree.ElementTree遍历xml所有节点实例详解、python xml解析之 xml.etree.ElementTree、Python XML解析之ElementTree的相关信息,请在本站查询。

本文标签: