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 : &#234; - &#234;
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


&#234;

>>> 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>

>>> 
GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:2 个月前 )
c345bb45 6 个月前
a07f3a59 * Update transition.md * Update table.md * Update transition.md * Update table.md * Update transition.md * Update table.md * Update table.md * Update transition.md * Update popover.md 7 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐