为什么lxml里面没有uuid.fromstringg

推荐这篇日记的豆列
······1100人阅读
python(21)
lxml takes all the pain out of XML.
Stephan Richter
&&& lxml是Python语言里和XML以及HTML工作的功能最丰富和最容易使用的库。lxml是为libxml2和libxslt库的一个Python化的绑定。它与众不同的地方是它兼顾了这些库的速度和功能完整性,以及纯Python API的简洁性,大部分与熟知的ElementTree API兼容但比之更优越。
安装lxml:
要求:需要Python2.3或更后的版本
使用easy_install工具,以超级用户或管理员的角色run下面的命令:
easy_install lxml
在windows下,最好指定版本号:easy_install lxml==2.2.6
使用lxml进行开发
lxml.etree指南
通常使用lxml.etree的方式
&&& from lxml import etree
Element类,一个Element是ElementTree API的主要容器类,大部分的XML tree功能都是通过这个类来访问的。Elements可以非常容易地通过Element工厂方法来创建。
&&& root = etree.Element(&root&)
元素的XML tag名字是通过tag属性来访问的
&&& print root.tag # root
Elements是在XML树状结构中组织的,为创建子元素并将它们加到父元素上,可以使用append()方法。
&&& root.append( etree.Element(&child1&) )
我们还有更高效的方法:SubElement工厂方法,它使用和Element工厂方法相同的参数,不过额外需要父节点作第一个参数:
&&& child2 = etree.SubElement(root, &child2&)
&&& child3 = etree.SubElement(root, &child3&)
可以使用tostring()方法来看得到的XML
&&& print etree.tostring(root, pretty_print=True)
元素是列表
&&& child = root[0]
&&& print child.tag
&&& print len(root)
&&& root.index(root[1]) # lxml.etree only!
打印所有子节点:
&&& children = list(root)
&&& for child in root:
... print(child.tag)
可以使用insert()方法插入新的子节点:
&&& root.insert(0, etree.Element(&child0&))
删除子节点:
&&& root[0] = root[-1] # this moves the element!
&&& for child in root:
... print(child.tag)
如果想把一个元素拷贝到不同的地方,需要创建一个独立的deep copy。
&&& from copy import deepcopy
&&& element = etree.Element(&neu&)
&&& element.append( deepcopy(root[1]) )
&&& print(element[0].tag)
&&& print([ c.tag for c in root ])
[’child3’, ’child1’, ’child2’]
getparent()返回父节点:
&&& root is root[0].getparent() # lxml.etree only!
元素的兄弟或邻居节点是通过next和previous属性来访问的
The siblings (or neighbours) of an element are accessed as next and previous elements:
&&& root[0] is root[1].getprevious() # lxml.etree only!
&&& root[1] is root[0].getnext() # lxml.etree only!
带属性的元素
XML元素支持属性,可以用Element工厂方法直接创建。
&&& root = etree.Element(&root&, interesting=&totally&)
&&& etree.tostring(root)
b’&root interesting=&totally&/&’
可以使用set和get方法访问这些属性:
&&& print root.get(&interesting&)
&&& root.set(&interesting&, &somewhat&)
&&& print root.get(&interesting&)
也可以使用attrib性质的字典接口
&&& attributes = root.attrib
&&& print(attributes[&interesting&])
&&& print(attributes.get(&hello&))
&&& attributes[&hello&] = &Guten Tag&
&&& print(attributes.get(&hello&))
&&& print(root.get(&hello&))
元素可以包含文字:
&&& root = etree.Element(&root&)
&&& root.text = &TEXT&
&&& print(root.text)
&&& etree.tostring(root)
’&root&TEXT&/root&’
如果XML用在(X)HTML中,文本也可以在不同的元素中显示:
&html&&body&Hello&br/&World&/body&&/html&
元素有tail属性,它包含XML 树中元素直接跟的,直到下个元素的文本。
&&& html = etree.Element(&html&)
&&& body = etree.SubElement(html, &body&)
&&& body.text = &TEXT&
&&& etree.tostring(html)
b’&html&&body&TEXT&/body&&/html&’
&&& br = etree.SubElement(body, &br&)
&&& etree.tostring(html)
b’&html&&body&TEXT&br/&&/body&&/html&’
&&& br.tail = &TAIL&
&&& etree.tostring(html)
b’&html&&body&TEXT&br/&TAIL&/body&&/html&’
使用XPath查找文本
另一个抽取XML树的文本内容是XPath,
&&& print(html.xpath(&string()&)) # lxml.etree only!
&&& print(html.xpath(&//text()&)) # lxml.etree only!
[’TEXT’, ’TAIL’]
如果经常使用,可以包装成一个方法:
&&& build_text_list = etree.XPath(&//text()&) # lxml.etree only!
&&& print(build_text_list(html))
[’TEXT’, ’TAIL’]
也可以通过getparent方法得到父节点
&&& texts = build_text_list(html)
&&& print(texts[0])
&&& parent = texts[0].getparent()
&&& print(parent.tag)
&&& print(texts[1])
&&& print(texts[1].getparent().tag)
You can also find out if it’s normal text content or tail text:
&&& print(texts[0].is_text)
&&& print(texts[1].is_text)
&&& print(texts[1].is_tail)
树的迭代:
Elements提供一个树的迭代器可以迭代访问树的元素。
&&& root = etree.Element(&root&)
&&& etree.SubElement(root, &child&).text = &Child 1&
&&& etree.SubElement(root, &child&).text = &Child 2&
&&& etree.SubElement(root, &another&).text = &Child 3&
&&& print(etree.tostring(root, pretty_print=True))
&child&Child 1&/child&
&child&Child 2&/child&
&another&Child 3&/another&
&&& for element in root.iter():
... print(&%s - %s& % (element.tag, element.text))
root&– None
child - Child 1
child - Child 2
another - Child 3
如果知道感兴趣的tag,可以把tag的名字传给iter方法,起到过滤作用。
&&& for element in root.iter(&child&):
... print(&%s - %s& % (element.tag, element.text))
child - Child 1
child - Child 2
默认情况下,迭代器得到一个树的所有节点,包括ProcessingInstructions, Comments and Entity的实例。如果想确认只有Elements对象返回,可以把Element factory作为参数传入。
&&& root.append(etree.Entity(&#234&))
&&& root.ment(&some comment&))
&&& for element in root.iter():
... if isinstance(element.tag, basestring):
... print(&%s - %s& % (element.tag, element.text))
... print(&SPECIAL: %s - %s& % (element, element.text))
root - None
child - Child 1
child - Child 2
another - 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 - Child 1
child - Child 2
another - Child 3
&&& for element in root.iter(tag=etree.Entity):
... print(element.text)
序列化通常使用tostring()方法来返回一个字符串,或者ElementTree.write()方法来写入一个文件,一个类文件的对象,或者一个URL(通过FTP的PUT或者HTTP的POST)。二者都使用相同的关键字参数比如pretty_print来格式化输出或者encoding来选择一个特定的输出编码而不是简单的ASCII。
&&& root = etree.XML(&&root&&a&&b/&&/a&&/root&&)
&&& etree.tostring(root)
’&root&&a&&b/&&/a&&/root&’
&&& print etree.tostring(root, xml_declaration=True)
&?xml version=’1.0’ encoding=’ASCII’?&
&root&&a&&b/&&/a&&/root&
&&& print etree.tostring(root, encoding=&iso-8859-1&)
&?xml version=’1.0’ encoding=’iso-8859-1’?&
&root&&a&&b/&&/a&&/root&
&&& print etree.tostring(root, pretty_print=True)
Note that pretty printing appends a newline at the end.
注意pretty打印在末尾添加一个新行。
从lxml2.0起,serialisation可以做的不止XML序列化,可以序列化到HTML或者通过传递函数关键字来提取文本内容。
&&& root = etree.XML(&&html&&head/&&body&&p&Hello&br/&World&/p&&/body&&/html&&)
&&& etree.tostring(root) # default: method = ’xml’
’&html&&head/&&body&&p&Hello&br/&World&/p&&/body&&/html&’
&&& etree.tostring(root, method=&xml&) # same as above
’&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&’
&&& print etree.tostring(root, method=&html&, pretty_print=True)
&head&&/head&
&body&&p&Hello&br&World&/p&&/body&
&&& etree.tostring(root, method=&text&)
b’HelloWorld’
对XML序列化而言,默认的文本编码是ASCII
&&& br = root.find(&.//br&)
&&& br.tail = u&W/xf6rld&
&&& etree.tostring(root, method=&text&) # doctest: +ELLIPSIS
Traceback (most recent call last):
UnicodeEncodeError: ’ascii’ codec can’t encode character u’/xf6’ ...
&&&etree.tostring(root, method=&text&, encoding=&UTF-8&)
b’HelloW/xc3/xb6rld’
&&& etree.tostring(root, encoding=unicode, method=&text&)
u’HelloW/xf6rld’
ElementTree类:
一个ElementTree主要是围绕在一个有根节点的树的文档包装类。它提供了很多方法来解析,序列化以及一般的文档处理。一个最大的区别是它作为一个整体文档来序列化。与之相对的是序列化成单个的元素。
&&& tree = etree.parse(StringIO(&&&/
&&?xml version=&1.0&?&
&&!DOCTYPE root SYSTEM &test& [ &!ENTITY tasty &eggs&& ]&
&&& print(tree.docinfo.doctype)
&!DOCTYPE root SYSTEM &test&&
&&& # lxml 1.3.4 and later
&&& print(etree.tostring(tree))
&!DOCTYPE root SYSTEM &test& [
&!ENTITY tasty &eggs&&
&a&eggs&/a&
&&& # lxml 1.3.4 and later
&&& print(etree.tostring(etree.ElementTree(tree.getroot())))
&!DOCTYPE root SYSTEM &test& [
&!ENTITY tasty &eggs&&
&a&eggs&/a&
&&& # ElementTree and lxml &= 1.3.3
&&& print(etree.tostring(tree.getroot()))
&a&eggs&/a&
从字符串和文件中解析:
fromstring()是解析字符串最容易的方法
&&& some_xml_data = &&root&data&/root&&
&&& root = etree.fromstring(some_xml_data)
&&& print root.tag
&&& etree.tostring(root)
’&root&data&/root&’
XML()方法和fromstring()方法类似,但它主要用来把XML文字写入源文件。
&&& root = etree.XML(&&root&data&/root&&)
&&& print root.tag
&&& etree.tostring(root)
’&root&data&/root&’
parse()方法用来从文件或者类文件对象中解析
&&& some_file_like = StringIO.StringIO(&&root&data&/root&&)
&&& tree = etree.parse(some_file_like)
&&& etree.tostring(tree)
’&root&data&/root&’
注意parse()返回的是一个ElementTree对象,而不是字符串解析方法的Element对象。
&&& root = tree.getroot()
&&& print root.tag
&&& etree.tostring(root)
’&root&data&/root&’
解析器对象:lxml.etree在默认情况下使用带默认配置的标准解析器,如果想配置解析器,可以创建自己的实例。
&&& parser = etree.XMLParser(remove_blank_text=True) # lxml.etree only!
本例在解析的时候创建了一个移除tags之间的空的文本的解析器,这可以减少tree的大小以及避免不定的tail,如果你知道空白内容对你来说是没有任何意义的话。
&&& root = etree.XML(&&root& &a/& &b& &/b& &/root&&, parser)
&&& etree.tostring(root)
b’&root&&a/&&b& &/b&&/root&’
&&& for element in root.iter(&*&):
... if element.text is not None and not element.text.strip():
... element.text = None
&&& etree.tostring(root)
b’&root&&a/&&b/&&/root&’
递增解析:
lxml.etree提供了两种方法来实现递增的逐步的解析。一个方法是通过类文件对象,它重复调用read() 方法。
&&& class DataSource:
... data = [ b&&roo&, b&t&&&, b&a/&, b&&&&, b&/root&& ]
... def read(self, requested_size):
... return self.data.pop(0)
... except IndexError:
... return b’’
&&& tree = etree.parse(DataSource())
&&& etree.tostring(tree)
b’&root&&a/&&/root&’
第二个方法是通过feed解析器接口,由feed(data)&和 close() 方法提供
&&& parser = etree.XMLParser()
&&& parser.feed(&&roo&)
&&& parser.feed(&t&&&)
&&& parser.feed(&a/&)
&&& parser.feed(&&&&)
&&& parser.feed(&/root&&)
&&& root = parser.close()
&&& etree.tostring(root)
’&root&&a/&&/root&’
在调用close() 方法(或者当有exception发生的时候),可以通过调用feed() 方法重新使用parser:
&&& parser.feed(&&root/&&)
&&& root = parser.close()
&&& etree.tostring(root)
b’&root/&’
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:109504次
积分:1691
积分:1691
排名:千里之外
原创:57篇
转载:37篇
(1)(1)(2)(1)(1)(10)(3)(6)(3)(5)(1)(1)(2)(7)(2)(4)(2)(2)(2)(3)(5)(6)(9)(10)(2)(2)(1)Python lxml教程 - 简书
Python lxml教程
这两天因为要处理XML,研究了一下lxml库,做个总结。
我在处理XML时,最想了解的三个问题是:
问题1:有一个XML文件,如何解析
问题2:解析后,如果查找、定位某个标签
问题3:定位后如何操作标签,比如访问属性、文本内容等
本文就是按这三个问题组织的,文本中代码都在Python 3.5中运行通过。
开始之前,首先是导入模块,该库常用的XML处理功能都在lxml.etree中,可用下面的语句导入:
&&& from lxml import etree
这一节回答问题3。
Element是XML处理的核心类,Element对象可以直观的理解为XML的节点,大部分XML节点的处理都是围绕该类进行的。这部分包括三个内容:节点的操作、节点属性的操作、节点内文本的操作。
1、创建Element对象
直接使用Element方法,参数即节点名称。
&&& root = etree.Element('root')
&&& print(root)
&Element root at 0x2da0708&
2、获取节点名称
使用tag属性,获取节点的名称。
&&& print(root.tag)
3、输出XML内容
使用tostring方法输出XML内容(后文还会有补充介绍),参数为Element对象。
&&& print(etree.tostring(root))
b'&root&&child1/&&child2/&&child3/&&/root&'
4、添加子节点
使用SubElement方法创建子节点,第一个参数为父节点(Element对象),第二个参数为子节点名称。
&&& child1 = etree.SubElement(root, 'child1')
&&& child2 = etree.SubElement(root, 'child2')
&&& child3 = etree.SubElement(root, 'child3')
5、删除子节点
使用remove方法删除指定节点,参数为Element对象。clear方法清空所有节点。
&&& root.remove(child1)
# 删除指定子节点
&&& print(etree.tostring(root))
b'&root&&child2/&&child3/&&/root&'
&&& root.clear()
# 清除所有子节点
&&& print(etree.tostring(root))
b'&root/&'
6、以列表的方式操作子节点
可以将Element对象的子节点视为列表进行各种操作:
&&& child = root[0]
# 下标访问
&&& print(child.tag)
&&& print(len(root))
# 子节点数量
&&& root.index(child2)
# 获取索引号
&&& for child in root:
print(child.tag)
&&& root.insert(0, etree.Element('child0'))
&&& start = root[:1]
&&& end = root[-1:]
&&& print(start[0].tag)
&&& print(end[0].tag)
&&& root.append( etree.Element('child4') )
# 尾部添加
&&& print(etree.tostring(root))
b'&root&&child0/&&child1/&&child2/&&child3/&&child4/&&/root&'
其实前面讲到的删除子节点的两个方法remove和clear也和列表相似。
7、获取父节点
使用getparent方法可以获取父节点。
&&& print(child1.getparent().tag)
属性是以key-value的方式存储的,就像字典一样。
1、创建属性
可以在创建Element对象时同步创建属性,第二个参数即为属性名和属性值:
&&& root = etree.Element('root', interesting='totally')
&&& print(etree.tostring(root))
b'&root interesting="totally"/&'
也可以使用set方法给已有的Element对象添加属性,两个参数分别为属性名和属性值:
&&& root.set('hello', 'Huhu')
&&& print(etree.tostring(root))
b'&root interesting="totally" hello="Huhu"/&'
2、获取属性
属性是以key-value的方式存储的,就像字典一样。直接看例子
# get方法获得某一个属性值
&&& print(root.get('interesting'))
# keys方法获取所有的属性名
&&& sorted(root.keys())
['hello', 'interesting']
# items方法获取所有的键值对
&&& for name, value in sorted(root.items()):
print('%s = %r' % (name, value))
hello = 'Huhu'
interesting = 'totally'
也可以用attrib属性一次拿到所有的属性及属性值存于字典中:
&&& attributes = root.attrib
&&& print(attributes)
{'interesting': 'totally', 'hello': 'Huhu'}
&&& attributes['good'] = 'Bye'
# 字典的修改影响节点
&&& print(root.get('good'))
标签及标签的属性操作介绍完了,最后就剩下标签内的文本了。可以使用text和tail属性、或XPath的方式来访问文本内容。
1、text和tail属性
一般情况,可以用Element的text属性访问标签的文本。
&&& root = etree.Element('root')
&&& root.text = 'Hello, World!'
&&& print(root.text)
Hello, World!
&&& print(etree.tostring(root))
b'&root&Hello, World!&/root&'
XML的标签一般是成对出现的,有开有关,但像HTML则可能出现单一的标签,比如下面这段代码中的&br/&。
&html&&body&Text&br/&Tail&/body&&/html&
Element类提供了tail属性支持单一标签的文本获取。
&&& html = etree.Element('html')
&&& body = etree.SubElement(html, 'body')
&&& body.text = 'Text'
&&& print(etree.tostring(html))
b'&html&&body&Text&/body&&/html&'
&&& br = etree.SubElement(body, 'br')
&&& print(etree.tostring(html))
b'&html&&body&Text&br/&&/body&&/html&'
# tail仅在该标签后面追加文本
&&& br.tail = 'Tail'
&&& print(etree.tostring(br))
b'&br/&Tail'
&&& print(etree.tostring(html))
b'&html&&body&Text&br/&Tail&/body&&/html&'
# tostring方法增加method参数,过滤单一标签,输出全部文本
&&& print(etree.tostring(html, method='text'))
b'TextTail'
2、XPath方式
# 方式一:过滤单一标签,返回文本
&&& print(html.xpath('string()'))
# 方式二:返回列表,以单一标签为分隔
&&& print(html.xpath('//text()'))
['Text', 'Tail']
方法二获得的列表,每个元素都会带上它所属节点及文本类型信息,如下:
&&& texts = html.xpath('//text()'))
&&& print(texts[0])
# 所属节点
&&& parent = texts[0].getparent()
&&& print(parent.tag)
&&& print(texts[1], texts[1].getparent().tag)
# 文本类型:是普通文本还是tail文本
&&& print(texts[0].is_text)
&&& print(texts[1].is_text)
&&& print(texts[1].is_tail)
文件解析与输出
这一节回答问题1。
这部分讲述如何将XML文件解析为Element对象,以及如何将Element对象输出为XML文件。
1、文件解析
文件解析常用的有fromstring、XML和HTML三个方法。接受的参数都是字符串。
&&& xml_data = '&root&data&/root&'
# fromstring方法
&&& root1 = etree.fromstring(xml_data)
&&& print(root1.tag)
&&& print(etree.tostring(root1))
b'&root&data&/root&'
# XML方法,与fromstring方法基本一样
&&& root2 = etree.XML(xml_data)
&&& print(root2.tag)
&&& print(etree.tostring(root2))
b'&root&data&/root&'
# HTML方法,如果没有&html&和&body&标签,会自动补上
&&& root3 = etree.HTML(xml_data)
&&& print(root3.tag)
&&& print(etree.tostring(root3))
b'&html&&body&&root&data&/root&&/body&&/html&'
输出其实就是前面一直在用的tostring方法了,这里补充xml_declaration和encoding两个参数,前者是XML声明,后者是指定编码。
&&& root = etree.XML('&root&&a&&b/&&/a&&/root&')
&&& print(etree.tostring(root))
b'&root&&a&&b/&&/a&&/root&'
&&& print(etree.tostring(root, xml_declaration=True))
b"&?xml version='1.0' encoding='ASCII'?&\n&root&&a&&b/&&/a&&/root&"
# 指定编码
&&& print(etree.tostring(root, encoding='iso-8859-1'))
b"&?xml version='1.0' encoding='iso-8859-1'?&\n&root&&a&&b/&&/a&&/root&"
ElementPath
这一节回答问题2。
讲ElementPath前,需要引入ElementTree类,一个ElementTree对象可理解为一个完整的XML树,每个节点都是一个Element对象。而ElementPath则相当于XML中的XPath。用于搜索和定位Element元素。
这里介绍两个常用方法,可以满足大部分搜索、查询需求,它们的参数都是XPath语句:
findall():返回所有匹配的元素,返回列表
find():返回匹配到的第一个元素
&&& root = etree.XML("&root&&a x='123'&aText&b/&&c/&&b/&&/a&&/root&")
# 查找第一个b标签
&&& print(root.find('b'))
&&& print(root.find('a').tag)
# 查找所有b标签,返回Element对象组成的列表
&&& [ b.tag for b in root.findall('.//b') ]
['b', 'b']
# 根据属性查询
&&& print(root.findall('.//a[@x]')[0].tag)
&&& print(root.findall('.//a[@y]'))
lxml官方文档:
XPath语法:
介绍戳这里:/about.html

我要回帖

更多关于 numpy fromstring 的文章

 

随机推荐