我试着用lxml.etree解析XML文件并将文本查找到XML元素中。在
XML文件可以是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/
http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>2002-06-01T19:20:30Z</responseDate>
<request verb="ListRecords" from="1998-01-15"
set="physics:hep"
metadataPrefix="oai_rfc1807">
http://an.oa.org/OAI-script</request>
<ListRecords>
<record>
<header>
<identifier>oai:arXiv.org:hep-th/9901001</identifier>
<datestamp>1999-12-25</datestamp>
<setSpec>physics:hep</setSpec>
<setSpec>math</setSpec>
</header>
<metadata>
<rfc1807 xmlns=
"http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt
http://www.openarchives.org/OAI/1.1/rfc1807.xsd">
<bib-version>v2</bib-version>
<id>hep-th/9901001</id>
<entry>January 1, 1999</entry>
<title>Investigations of Radioactivity</title>
<author>Ernest Rutherford</author>
<date>March 30, 1999</date>
</rfc1807>
</metadata>
<about>
<oai_dc:dc
xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/
http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:publisher>Los Alamos arXiv</dc:publisher>
<dc:rights>Metadata may be used without restrictions as long as
the oai identifier remains attached to it.</dc:rights>
</oai_dc:dc>
</about>
</record>
<record>
<header status="deleted">
<identifier>oai:arXiv.org:hep-th/9901007</identifier>
<datestamp>1999-12-21</datestamp>
</header>
</record>
</ListRecords>
</OAI-PMH>
对于下面的部分,我们假设doc = etree.parse("/tmp/test.xml")
其中文本.xml包含上面粘贴的xml。在
首先,我尝试使用doc.findall(".//record")
查找所有的<record>
元素,但它返回一个空列表。在
其次,对于一个给定的单词,我想检查它是否在<dc:publisher>
中。
为了实现这一点,我首先尝试和前面一样:doc.findall(".//publisher")
但是我有同样的问题。。。我很确定所有这些都与名称空间相关,但我不知道如何处理它们。在
我已经阅读了libxmltutorial,并在一个基本的xml文件(没有任何名称空间)上尝试了findall
方法的示例,结果证明了这一点。在
免责声明:我正在使用标准库xml.etree.ElementTree模块,而不是lxml库(尽管据我所知,这是lxml的一个子集)。我确信有一个答案比我的答案简单得多,它使用lxml和XPATH,但我不知道。在
命名空间问题
你可能会说名称空间是对的。XML文件中没有
record
元素,但文件中有两个{http://www.openarchives.org/OAI/2.0/}record
标记。如下所示:所以,举个例子
^{pr2}$返回
None
,而返回
ListRecords
元素。在注意,我使用的是
find
方法,因为标准库ElementTree没有xpath
方法。在可能的解决方案
解决这个问题的一种方法是获取名称空间前缀,并将其添加到要查找的标记中。你可以用
在根元素
e
上查找名称空间,尽管我确信有更好的方法来完成此操作。在现在,我们可以定义函数来提取我们想要的标记我们有一个可选的名称空间前缀:
所以现在我们可以写:
替代方案
另一种解决方案可能是编写一个函数来搜索以您感兴趣的标记结尾的所有标记,例如:
这里根本不需要处理名称空间。在
@Chris answer非常好,它也可以与}的方法相同):
lxml
一起工作。下面是另一种使用lxml
(与xpath
而不是{正如Chris已经提到的,您还可以使用lxml和xpath。由于xpath不允许您像
{http://www.openarchives.org/OAI/2.0/}record
(所谓的“James Clark notation”*)那样完整地编写名称空间名称,因此您必须使用前缀,并为xpath引擎提供一个前缀到名称空间uri映射。在以lxml为例(假设您已经拥有所需的
tree
对象):这将选择具有包含单词“Alamos”的子元素
{http://purl.org/dc/elements/1.1/}dc
的所有{http://www.openarchives.org/OAI/2.0/}record
元素。在[*]这来自于一个article,其中James Clark解释了XML名称空间,不熟悉名称空间的每个人都应该阅读本文!(即使是很久以前写的)
相关问题 更多 >
编程相关推荐