在用"丑陋"的XML读取现有文件并进行一些修改后,漂亮的打印不起作用.我试过了etree.write(FILE_NAME, pretty_print=True)
.
我有以下XML:
<testsuites tests="14" failures="0" disabled="0" errors="0" time="0.306" name="AllTests">
<testsuite name="AIR" tests="14" failures="0" disabled="0" errors="0" time="0.306">
....
Run Code Online (Sandbox Code Playgroud)
我这样使用它:
tree = etree.parse('original.xml')
root = tree.getroot()
...
# modifications
...
with open(FILE_NAME, "w") as f:
tree.write(f, pretty_print=True)
Run Code Online (Sandbox Code Playgroud) 我需要检查xml文件中是否存在某个标记.
例如,我想查看此代码段中是否存在该标记:
<main>
<elem1/>
<elem2>Hi</elem2>
<elem3/>
...
</main>
Run Code Online (Sandbox Code Playgroud)
目前,我正在使用一个带有错误检查的丑陋黑客,如下所示:
try:
if root.elem1.tag:
foo = elem1
except AttributeError:
foo = "error finding elem1"
Run Code Online (Sandbox Code Playgroud)
如果无法找到节点,我也想自定义字符串(即"无法找到-tagname-").
我必须检查一长串变量,我不想重复代码100次.
有什么建议?
编辑:
以下是实际xml文件的片段:
<main>
<asset name="Virtual Dvaered Unpresence">
<virtual/>
<presence>
<faction>Dvaered</faction>
<value>-1000.000000</value>
<range>0</range>
</presence>
</asset>
<asset name="Virtual Empire Small">
<virtual/>
<presence>
<faction>Empire</faction>
<value>100.000000</value>
<range>2</range>
</presence>
</asset>
</main>
Run Code Online (Sandbox Code Playgroud)
我想检查标签是否存在,如果是,则获取内容.
编辑编辑:好的,我将结合两个答案,但我只能投一票.抱歉.
编辑3:关于XPath的相关问题:Python lxml(objectify):Xpath麻烦
因为我第二次遇到这个烦人的问题,我觉得这个问题会有所帮助.
有时候我必须从XML文档中获取Elements,但是这样做的方法很尴尬.
我想知道一个python库,它可以实现我想要的,一种优雅的方式来表示我的XPath,一种在前缀中自动注册命名空间的方法,或者在内置XML实现中的隐藏首选项,或者在lxml中完全删除命名空间.澄清之后,除非你已经知道我想要什么:)
实施例-doc的:
<root xmlns="http://really-long-namespace.uri"
xmlns:other="http://with-ambivalent.end/#">
<other:elem/>
</root>
Run Code Online (Sandbox Code Playgroud)
ElementTree API是唯一内置的(我知道)提供XPath查询.但它需要我使用"UNames".这看起来像这样:/{http://really-long-namespace.uri}root/{http://with-ambivalent.end/#}elem
如您所见,这些都非常冗长.我可以通过以下方式缩短它们:
default_ns = "http://really-long-namespace.uri"
other_ns = "http://with-ambivalent.end/#"
doc.find("/{{{0}}}root/{{{1}}}elem".format(default_ns, other_ns))
Run Code Online (Sandbox Code Playgroud)
但是,这是双方{{{丑陋}}}和脆弱的,因为http…end/#
≅ http…end#
≅ http…end/
≅ http…end
和我是谁知道哪个变种会用吗?
此外,lxml支持名称空间前缀,但它既不使用文档中的名称前缀,也不提供处理默认名称空间的自动方法.我仍然需要从每个命名空间中获取一个元素以从文档中检索它.命名空间属性不会保留,因此也无法自动从这些属性中检索它们.
有一种与命名空间无关的XPath查询方式,但它在内置实现中既详细又丑陋且不可用: /*[local-name() = 'root']/*[local-name() = 'elem']
我想找到一个库,选项或通用的XPath变形函数,通过输入以下内容来实现上述示例...
/root/elem
/root/other:elem
...加上可能是一些我确实想要使用文档前缀或剥离命名空间的语句.
进一步澄清:虽然我目前的用例很简单,但将来我将不得不使用更复杂的用例.
谢谢阅读!
用户samplebias将我的注意力引向了py-dom-xpath ; 正是我在寻找什么.我的实际代码现在看起来像这样:
#parse the document into a DOM tree
rdf_tree = xml.dom.minidom.parse("install.rdf")
#read the default namespace and prefix from the root node
context = xpath.XPathContext(rdf_tree)
name = context.findvalue("//em:id", rdf_tree)
version …
Run Code Online (Sandbox Code Playgroud) 这最终消耗了我所有可用的内存,然后该进程被终止.我已经尝试将标签更改schedule
为"较小"标签,但这并没有什么区别.
我做错了什么/如何处理这个大文件iterparse()
?
import lxml.etree
for schedule in lxml.etree.iterparse('really-big-file.xml', tag='schedule'):
print "why does this consume all my memory?"
Run Code Online (Sandbox Code Playgroud)
我可以轻松地将其切割并以较小的块处理它,但这比我想要的更糟糕.
我正在尝试使用python 2.5和2.7上的LXML解析器解析破坏的HTML
与LXML文档(http://lxml.de/parsing.html#parsing-html)不同,解析损坏的HTML不起作用:
from lxml import etree
import StringIO
broken_html = "<html><head><title>test<body><h1>page title</h3>"
parser = etree.HTMLParser()
tree = etree.parse(StringIO.StringIO(broken_html))
Run Code Online (Sandbox Code Playgroud)
结果:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 2954, in lxml.etree.parse (src/lxml/lxml.etree.c:56220)
File "parser.pxi", line 1550, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:82482)
File "parser.pxi", line 1578, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82764)
File "parser.pxi", line 1457, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:81562)
File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:78232)
File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74488)
File "parser.pxi", line 650, in …
Run Code Online (Sandbox Code Playgroud) 我正在进行网络抓取项目,并遇到速度问题.为了尝试修复它,我想使用lxml而不是html.parser作为BeautifulSoup的解析器.我已经能够做到这一点:
soup = bs4.BeautifulSoup(html, 'lxml')
Run Code Online (Sandbox Code Playgroud)
但我不想'lxml'
每次打电话给BeautifulSoup都要反复输入.有没有办法在程序开始时设置一次使用哪个解析器?
我试图以一种内存有效的方式解析一个带有lxml的巨大xml文件(即从磁盘懒洋洋地流式传输,而不是将整个文件加载到内存中).不幸的是,该文件包含一些破坏默认解析器的坏ascii字符.如果我设置recover = True,则解析器可以工作,但是iterparse方法不会使用recover参数或自定义解析器对象.有谁知道如何使用iterparse来解析破碎的xml?
#this works, but loads the whole file into memory
parser = lxml.etree.XMLParser(recover=True) #recovers from bad characters.
tree = lxml.etree.parse(filename, parser)
#how do I do the equivalent with iterparse? (using iterparse so the file can be streamed lazily from disk)
context = lxml.etree.iterparse(filename, tag='RECORD')
#record contains 6 elements that I need to extract the text from
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助!
编辑 - 以下是我遇到的编码错误类型的示例:
In [17]: data
Out[17]: '\t<articletext><p>The cafeteria rang with excited voices. Our barbershop quartet, The Bell \r Tones was …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用html5lib将html页面解析为我可以使用xpath查询的内容.html5lib文档接近零,我花了太多时间试图解决这个问题.最终目标是拉出表的第二行:
<html>
<table>
<tr><td>Header</td></tr>
<tr><td>Want This</td></tr>
</table>
</html>
Run Code Online (Sandbox Code Playgroud)
所以试试吧:
>>> doc = html5lib.parse('<html><table><tr><td>Header</td></tr><tr><td>Want This</td> </tr></table></html>', treebuilder='lxml')
>>> doc
<lxml.etree._ElementTree object at 0x1a1c290>
Run Code Online (Sandbox Code Playgroud)
看起来不错,让我们看看我们还有什么:
>>> root = doc.getroot()
>>> print(lxml.etree.tostring(root))
<html:html xmlns:html="http://www.w3.org/1999/xhtml"><html:head/><html:body><html:table><html:tbody><html:tr><html:td>Header</html:td></html:tr><html:tr><html:td>Want This</html:td></html:tr></html:tbody></html:table></html:body></html:html>
Run Code Online (Sandbox Code Playgroud)
大笑?
认真.我打算使用一些xpath来获取我想要的数据,但这似乎不起作用.那我该怎么办?我愿意尝试不同的库和方法.
我正在使用lxml(2.2.8)来创建和编写一些XML(特别是XGMML).将要阅读它的应用程序显然相当挑剔,并希望看到一个顶级元素:
<graph label="Test" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="h
ttp://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-
ns#" xmlns:cy="http://www.cytoscape.org" xmlns="http://www.cs.rpi.edu/XGMML" di
rected="1">
Run Code Online (Sandbox Code Playgroud)
如何xmlns:
使用lxml 设置这些属性?如果我尝试明显的
root.attrib['xmlns:dc']='http://purl.org/dc/elements/1.1/'
root.attrib['xmlns:xlink']='http://www.w3.org/1999/xlink'
root.attrib['xmlns:rdf']='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
root.attrib['xmlns:cy']='http://www.cytoscape.org'
root.attrib['xmlns']='http://www.cs.rpi.edu/XGMML'
Run Code Online (Sandbox Code Playgroud)
lxml抛出一个 ValueError: Invalid attribute name u'xmlns:dc'
我过去曾经使用过很多XML和lxml来处理简单的事情,但是到目前为止还是设法避免需要知道关于命名空间的任何事情.
我有一个类似于以下的html文档:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
<div id="Symbols" class="cb">
<table class="quotes">
<tr><th>Code</th><th>Name</th>
<th style="text-align:right;">High</th>
<th style="text-align:right;">Low</th>
</tr>
<tr class="ro" onclick="location.href='/xyz.com/A.htm';" style="color:red;">
<td><a href="/xyz.com/A.htm" title="Display,A">A</a></td>
<td>A Inc.</td>
<td align="right">45.44</td>
<td align="right">44.26</td>
<tr class="re" onclick="location.href='/xyz.com/B.htm';" style="color:red;">
<td><a href="/xyz.com/B.htm" title="Display,B">B</a></td>
<td>B Inc.</td>
<td align="right">18.29</td>
<td align="right">17.92</td>
</div></html>
Run Code Online (Sandbox Code Playgroud)
我需要code/name/high/low
从表中提取信息.
我使用了Stack Over Flow中类似示例中的以下代码:
#############################
import urllib2
from lxml import html, etree
webpg = urllib2.urlopen(http://www.eoddata.com/stocklist/NYSE/A.htm).read()
table = html.fromstring(webpg)
for row in table.xpath('//table[@class="quotes"]/tbody/tr'):
for column in row.xpath('./th[position()>0]/text() | ./td[position()=1]/a/text() | ./td[position()>1]/text()'):
print column.strip(),
print
#############################
Run Code Online (Sandbox Code Playgroud)
我没有得到任何输出.我必须将第一个循环xpath更改table.xpath('//tr') …
lxml ×10
python ×10
xml ×4
xpath ×3
html ×2
cytoscape ×1
elementtree ×1
html-parsing ×1
html-table ×1
html5lib ×1
iterparse ×1
memory ×1
objectify ×1
parsing ×1
pretty-print ×1
sax ×1