lxml Element类相关的介绍
Element class
用lxml首先我们要导入相关库
>>>from lxml import etree
创建一个root节点
>>>root=etree.Element("root")
看看root是什么
>>> print root
<Element root at 0x3060108> #是Element类
>>> type(root)
<type 'lxml.etree._Element'>
打印节点的名字
>>>print(root.tag)
root
创建一个子节点并添加到父节点中
>>>root.append(etree.Element('child1'))
另一种创建子节点并添加到节点中的方式
>>> etree.SubElement(root,"child2")
<Element child2 at 0x2ef7b48>
>>> etree.SubElement(root,"child3")
<Element child3 at 0x305b208>
看看现在root都有什么内容了
>>> etree.tostring(root,pretty_print=True)
'<root>
<child1/>
<child2/>
<child3/>
</root>'
Elements are lists (Element类是python里的列表)
为了使获取子节点更直接和容易,elements模仿尽可能的模仿了正常python 列表的表现行为
我的理解为把Element 下的 SubElement组成的列表
#下标操作
>>> root[0].tag
'child1'
#负数下标
>>> root[-1].tag
'child3'
#列表的方法
>>> len(root)
3
>>> children = list(root)
>>> children
[<Element child1 at 0x305b208>, <Element child2 at 0x2f5eec8>, <Element child3 at 0x2f5e088>]
#列表的迭代
>>> for child in root:
print child.tag
child1
child2
child3
#列表的插入
>>> root.insert(0,etree.Element('child0'))
>>> len(root)
4
#列表的分片
>>> start = root[:1]
>>> start
[<Element child0 at 0x2f5eb08>]
#列表的负数分片
>>> end = root[-1:]
>>> end
[<Element child3 at 0x2f5e088>]
>>> print start[0].tag
child0
>>> print end[0].tag
child3
直到ElementTree1.3和lxml2.0,你可以用bool值 来测试Element有没有子节点
#这样作会得到一个警告
>>> if root:
print 1
Warning (from warnings module):
File "__main__", line 2
FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead.
1
注意
#创建一个节点p
a = etree.Element('p')
#节点p里的文本为something text
a.text = "something text"
# "<p>something text"
res = bool(a) #这里会是True
length = len(a) #这里length的长度为0
这会引起人们的惊讶和疑惑,因此,引入etree.iselement()方法
>>> etree.iselement(root)
True
>>> if len(root):
print "The root element has child"
The root element has child
下面是关于复制的特性
>>> for child in root:
print child.tag
child0
child1
child2
child3
>>> root[0] = root[-1] #这里会把列表的最后一个元素移到到第一个,而不是简单的复制
>>> for child in root:
print child.tag
child3
child1
child2
我们可能会对移动这个特性感到疑惑,来作一个关于list的实验
>>> lst = [0, 1, 2, 3]
>>> lst[0] = lst[-1]
>>> lst
[3, 1, 2, 3]
如果你想复制一个节点到别的地方,我们要用深复制copy.deepcopy()方法
>>> from copy import deepcopy
>>> root.insert(0,deepcopy(root[-1]))
>>> for child in root:
print child.tag
child2
child3
child1
child2
获取父节点
获取前一个节点
获取下一个节点
>>> root[0].getparent().tag
'root'
>>> root[1].getprevious().tag
'child2'
>>> root[0].getnext().tag
'child3'
为节点添加数据
Elements 用python的字典表示节点的属性
>>> root = etree.Element("root",interesting="totally")
>>> etree.tostring(root)
'<root interesting="totally"/>'
属性是一些无序的键值对,我们可以用Elements的类字典接口来处理这些属性
>>> root.get("interesting")
'totally'
>>> root.get("hello") #None
>>> root.set("hello", "huhu")
>>> root.get("hello")
'huhu'
>>> etree.tostring(root)
'<root interesting="totally" hello="huhu"/>'
>>> root.keys()
['interesting', 'hello']
>>> root.items()
[('interesting', 'totally'), ('hello', 'huhu')]
因为Element[index]等重载方法表示的是list,如果想要得到一个真正的类字典对象,可以使用Element.attrib属性
#获取对Elements对象属性的引用
>>> attributes = root.attrib
>>> attributes
{'interesting': 'totally', 'hello': 'huhu'}
#可以看到attributes并不是一个真正的字典,只是个类字典对象
>>> type(attributes)
<type 'lxml.etree._Attrib'>
>>> attributes["hello"]
'huhu'
>>> attributes.get("hello")
'huhu'
>>> attributes["hello"] = "heihei"
对attributes的修改会影响到Elements对象的属性字典,因为其是一个引用
>>> etree.tostring(root)
'<root interesting="totally" hello="heihei"/>'
Elements包含text属性
>>> root = etree.Element("root")
>>> root.text = "text"
>>> root.text
'text'
>>> etree.tostring(root)
'<root>text</root>'
在许多xml文档中,这是唯一出现文本的地方,在节点的最深处,并被标签包围
<a>
<b>
<c>some text</c>
</b>
</a>
但是如果是(x)html,情况就不一样了如相:
<html><body>Hello<br/>World</body></html>
<!-- 或者这样 -->
<div>text<span>ohter text</span>text else</div>
如上所示,br 标签两边都是文本我们该怎样获取World呢,我们先构造这样的元素
>>> html = etree.Element("html")
>>> body = etree.Element("body")
>>> br = etree.Element("br")
>>>
>>> body.text="Hello"
>>> body.append(br)
#可能这里你看不明白,这里的意思是在br的尾部加上"World"
>>> br.tail = "World"
>>> html.append(body)
>>> etree.tostring(html)
'<html><body>Hello<br/>World</body></html>'
Elements有了.text 和 .tail 两个表示文本的属性就足够表现任何文本在xml中,但是这样的特性也会造成问题如
>>> etree.tostring(br)
'<br/>World'
如果你不想Elements带上尾巴你可以这样作
>>> etree.tostring(br,with_tail=False)
'<br/>'
如果你不想要Elements的标签,而想要Elements的 .text 和 .tail你可以这样作
# 提取所有Elements的所有文本,不显示标签
>>> etree.tostring(html,method="text")
'HelloWorld'
Elements树的迭代
如果你想递归的迭代Elements,你可以使用Elements.iter()方法,它会根据文档的顺序产生迭代器
>>> root = etree.Element("root")
>>> child1 = etree.SubElement(root,"child")
>>> child1_son = etree.SubElement(child1,"son")
>>> child1_son.text = "child1 son"
>>> child2 = etree.SubElement(root,"child")
>>> another = etree.SubElement(root,"anothor").text = "Child 3"
>>> print etree.tostring(root, pretty_print=True)
<root>
<child>
<son>child1 son</son>
</child>
<child/>
<anothor>Child 3</anothor>
</root>
>>> for element in root.iter():
print "%s - %s" % (element.tag, element.text)
root - None
child - None
son - child1 son
child - None
anothor - Child 3
如果你想过滤一些想要的标签,你可以
for element in root.iter("anothor"):
print element.tag, element.text
在lxml3.0中,你可以放入多个过滤
>>> for element in root.iter("anothor", "son"):
print element.text, element.tag
child1 son son
Child 3 anothor
默认的,迭代器会遍历所有节点,包括处理命令,注释和,实体实例。如果你想只返回Elements objects
>>> root.append(etree.Entity("#234"))
>>> root.append(etree.Comment("some comment"))
>>> for element in root.iter():
if isinstance(element.tag, basestring):
print "%s - %s" % (element.tag, element.text)
else:
print "SPECIAL : %s - %s" % (element, element.text)
root - None
child - None
son - child1 son
child - None
anothor - Child 3
SPECIAL : ê - ê
SPECIAL : <!--some comment--> - some comment
>>> for element in root.iter(tag=etree.Element):
print "%s - %s" % (element.tag, element.text)
root - None
child - None
son - child1 son
child - None
anothor - Child 3
>>> for element in root.iter(tag=etree.Entity):
print element.text
ê
>>> for element in root.iter(tag=etree.Comment):
print element.text
some comment
输出通常使用tostring()方法返回字符串,或者ElementTree.write()方法写入一个文件,类文件对象,或者URL。这两个方法都接受同样的参数:像pretty_print (美化)encoding(编码)
print etree.tostring(root, xml_declaration=True, encoding="utf-8")
<?xml version='1.0' encoding='utf-8'?>
<root><a><b/></a></root>
在lxml2.0之后,
>>> from lxml import etree
>>> root = etree.XML('<html><head/><body><p>Hello<br/>World</p></body></html>')
>>> etree.tostring(root)
'<html><head/><body><p>Hello<br/>World</p></body></html>'
>>> etree.tostring(root,method="html")
'<html><head></head><body><p>Hello<br>World</p></body></html>'
>>> etree.tostring(root,method="text")
'HelloWorld'
>>> etree.tostring(root,method="xml")
'<html><head/><body><p>Hello<br/>World</p></body></html>'
>>> print etree.tostring(root, method="html")
<html><head></head><body><p>Hello<br>World</p></body></html>
>>> print etree.tostring(root, method="html",pretty_print=True)
<html>
<head></head>
<body><p>Hello<br>World</p></body>
</html>
>>>
更多推荐
所有评论(0)