当谈到在Python生成XML数据,还有我经常看到推荐的两个库:LXML和ElementTree的
据我所知,这两个库彼此非常相似.它们似乎都具有类似的模块名称,使用指南和功能.甚至导入语句也非常相似.
# Importing lxml and ElementTree
import lxml.etree
import xml.etree.ElementTree
Run Code Online (Sandbox Code Playgroud)
Python的库lxml和ElementTree库之间有什么区别?
我正在寻找使用ElementTree的XML到字典解析器,我已经找到了一些,但它们排除了属性,在我的情况下,我有很多属性.
当我尝试运行以下代码时,我在ElementTree中收到此错误:
SyntaxError: cannot use absolute path on element
Run Code Online (Sandbox Code Playgroud)
我的XML文档如下所示:
<Scripts>
<Script>
<StepList>
<Step>
<StepText>
</StepText>
<StepText>
</StepText>
</Step>
</StepList>
</Script>
</Scripts>
Run Code Online (Sandbox Code Playgroud)
码:
import xml.etree.ElementTree as ET
def search():
root = ET.parse(INPUT_FILE_PATH)
for target in root.findall("//Script"):
print target.attrib['name']
print target.findall("//StepText")
Run Code Online (Sandbox Code Playgroud)
我在Mac上使用Python 2.6.我使用Xpath语法错了吗?
基本上我想显示每个脚本元素名称属性,如果它包含带有特定文本的StepText元素.
我正在尝试解析OpenOffice ODS电子表格中的内容.ods格式本质上只是一个包含许多文档的zipfile.电子表格的内容存储在'content.xml'中.
import zipfile
from lxml import etree
zf = zipfile.ZipFile('spreadsheet.ods')
root = etree.parse(zf.open('content.xml'))
Run Code Online (Sandbox Code Playgroud)
电子表格的内容位于单元格中:
table = root.find('.//{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table')
Run Code Online (Sandbox Code Playgroud)
我们也可以直接寻找行:
rows = root.findall('.//{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table-row')
Run Code Online (Sandbox Code Playgroud)
各个元素知道命名空间:
>>> table.nsmap['table']
'urn:oasis:names:tc:opendocument:xmlns:table:1.0'
Run Code Online (Sandbox Code Playgroud)
如何在find/findall中直接使用命名空间?
显而易见的解决方案不起作用.
试图从表中获取行:
>>> root.findall('.//table:table')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 1792, in lxml.etree._ElementTree.findall (src/lxml/lxml.etree.c:41770)
File "lxml.etree.pyx", line 1297, in lxml.etree._Element.findall (src/lxml/lxml.etree.c:37027)
File "/usr/lib/python2.6/dist-packages/lxml/_elementpath.py", line 225, in findall
return list(iterfind(elem, path))
File "/usr/lib/python2.6/dist-packages/lxml/_elementpath.py", line 200, in iterfind
selector = _build_path_iterator(path)
File "/usr/lib/python2.6/dist-packages/lxml/_elementpath.py", line 184, in _build_path_iterator …Run Code Online (Sandbox Code Playgroud) 我对两个xml元素的等价感兴趣; 我发现测试元素的串串是有效的; 然而,这似乎是hacky.
有没有更好的方法来测试两个etree元素的等价性?
直接比较元素:
import xml.etree.ElementTree as etree
h1 = etree.Element('hat',{'color':'red'})
h2 = etree.Element('hat',{'color':'red'})
h1 == h2 # False
Run Code Online (Sandbox Code Playgroud)
将Elements作为字符串进行比较:
etree.tostring(h1) == etree.tostring(h2) # True
Run Code Online (Sandbox Code Playgroud) 在python 2.7(使用etree 1.3)中,我可以在这样的元素上抑制XML前缀:
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree as etree
>>> etree.VERSION
'1.3.0'
>>> something = etree.Element('{http://some.namespace}token')
>>> etree.tostring(something)
'<ns0:token xmlns:ns0="http://some.namespace" />'
>>> etree.register_namespace('', 'http://some.namespace')
>>> etree.tostring(something)
'<token xmlns="http://some.namespace" />'
Run Code Online (Sandbox Code Playgroud)
该register_namespace功能在1.3中添加.我试图以与版本1.2.6的python 2.6的etree兼容的方式删除前缀.这是我尝试过的:
Python 2.6.7 (r267:88850, Jul 31 2011, 19:30:54)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个与last.fm API进行交互的小脚本.
我有一些使用经验ElementTree,但我之前使用它的方式似乎不起作用,它返回一个空列表.
我删除了API密钥,因为我不确切知道它应该是多么私密,并举例说明了我收到的XML.
与API交互的类:
from xml.etree import ElementTree
import urllib
import urllib2
class Last_fmWrapper(object):
def __init__(self):
self.last_fm_api_key = '*****************************'
self.api_url = 'http://ws.audioscrobbler.com/2.0/'
def get_now_playing(self, last_fm_user, method):
self.last_fm_user = last_fm_user
self.method = method
parameters = {'user':self.last_fm_user, 'api_key':self.last_fm_api_key, 'method':self.method}
encoded_parameters = urllib.urlencode(parameters)
request = urllib2.Request(self.api_url, encoded_parameters)
response = urllib2.urlopen(request)
api_results = ElementTree.parse(response).findall('track')
# why does api_results == []?
def compare_tasteometer(self):
pass
def register_user(self):
pass
Run Code Online (Sandbox Code Playgroud)
调用get_now_playing方法Last_fmWrapper():
from last_fm_wrapper import Last_fmWrapper
last_fm = Last_fmWrapper()
now_playing = last_fm.get_now_playing('BiriBiriRG', 'user.getRecentTracks')
if …Run Code Online (Sandbox Code Playgroud) 我必须处理足够大的xml文档(高达1GB)并使用python解析它们.我正在使用iterparse()函数(SAX样式解析).
我关注的是,假设你有一个这样的xml
<?xml version="1.0" encoding="UTF-8" ?>
<families>
<family>
<name>Simpson</name>
<members>
<name>Homer</name>
<name>Marge</name>
<name>Bart</name>
</members>
</family>
<family>
<name>Griffin</name>
<members>
<name>Peter</name>
<name>Brian</name>
<name>Meg</name>
</members>
</family>
</families>
Run Code Online (Sandbox Code Playgroud)
问题是,当然知道我什么时候得到一个姓氏(如辛普森一家),当我得到一个家庭成员的名字时(例如荷马)
到目前为止我一直在做的是使用"开关",告诉我是否在"成员"标签内,代码看起来像这样
import xml.etree.cElementTree as ET
__author__ = 'moriano'
file_path = "test.xml"
context = ET.iterparse(file_path, events=("start", "end"))
# turn it into an iterator
context = iter(context)
on_members_tag = False
for event, elem in context:
tag = elem.tag
value = elem.text
if value :
value = value.encode('utf-8').strip()
if event == 'start' :
if tag == …Run Code Online (Sandbox Code Playgroud) 我在python中编写了一个相当简单的过滤器,使用ElementTree来处理某些xml文件的上下文.它或多或少都有效.
但它重新排序各种标签的属性,我希望它不会那样做.
有没有人知道我可以抛出一个开关使它按指定顺序保持?
我正在使用粒子物理工具,它具有基于xml文件的复杂但奇怪的有限配置系统.在许多方面,设置方式是各种静态数据文件的路径.这些路径硬编码到现有的xml中,并且没有用于根据环境变量设置或更改它们的工具,在我们的本地安装中,它们必须位于不同的位置.
这不是灾难,因为我们使用的组合源和构建控制工具允许我们使用本地副本隐藏某些文件.但是,即使数据字段是静态的,xml也不是,所以我编写了一个用于修复路径的脚本,但是在本地版本和主版本之间的属性重新排列差异比必要时更难阅读.
这是我第一次使用ElementTree旋转(只有我的第五或第六个python项目),所以也许我只是做错了.
为简单起见,代码看起来像这样:
tree = elementtree.ElementTree.parse(inputfile)
i = tree.getiterator()
for e in i:
e.text = filter(e.text)
tree.write(outputfile)
Run Code Online (Sandbox Code Playgroud)
合理还是愚蠢?
相关链接:
我正在尝试解析从Web检索的XML文档,但在解析此错误后崩溃了:
': failed to load external entity "<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="GreenButtonDataStyleSheet.xslt"?>
Run Code Online (Sandbox Code Playgroud)
这是下载的XML中的第二行.有没有办法阻止解析器尝试加载外部实体,或者另一种方法来解决这个问题?这是我到目前为止的代码:
import urllib2
import lxml.etree as etree
file = urllib2.urlopen("http://www.greenbuttondata.org/data/15MinLP_15Days.xml")
data = file.read()
file.close()
tree = etree.parse(data)
Run Code Online (Sandbox Code Playgroud) elementtree ×10
python ×10
xml ×7
lxml ×3
dictionary ×1
iterparse ×1
last.fm ×1
python-3.x ×1
sax ×1
xpath ×1