<p><em>免责声明:我正在使用标准库xml.etree.ElementTree模块,而不是lxml库(尽管据我所知,这是lxml的一个子集)。我确信有一个答案比我的答案简单得多,它使用lxml和XPATH,但我不知道。在</p>
<h2>命名空间问题</h2>
<p>你可能会说名称空间是对的。XML文件中没有<code>record</code>元素,但文件中有两个<code>{http://www.openarchives.org/OAI/2.0/}record</code>标记。如下所示:</p>
<pre><code>>>> import xml.etree.ElementTree as etree
>>> xml_string = ...Your XML to parse...
>>> e = etree.fromstring(xml_string)
# Let's see what the root element is
>>> e
<Element {http://www.openarchives.org/OAI/2.0/}OAI-PMH at 7f39ebf54f80>
# Let's see what children there are of the root element
>>> for child in e:
... print child
...
<Element {http://www.openarchives.org/OAI/2.0/}responseDate at 7f39ebf54fc8>
<Element {http://www.openarchives.org/OAI/2.0/}request at 7f39ebf58050>
<Element {http://www.openarchives.org/OAI/2.0/}ListRecords at 7f39ebf58098>
# Finally, let's get the children of the `ListRecords` element
>>> for child in e[-1]:
... print child
...
<Element {http://www.openarchives.org/OAI/2.0/}record at 7f39ebf580e0>
<Element {http://www.openarchives.org/OAI/2.0/}record at 7f39ebf58908>
</code></pre>
<p>所以,举个例子</p>
^{pr2}$
<p>返回<code>None</code>,而</p>
<pre><code>>>> e.find('{http://www.openarchives.org/OAI/2.0/}ListRecords'
<Element {http://www.openarchives.org/OAI/2.0/}ListRecords at 7f39ebf58098>
</code></pre>
<p>返回<code>ListRecords</code>元素。在</p>
<p>注意,我使用的是<code>find</code>方法,因为标准库ElementTree没有<code>xpath</code>方法。在</p>
<h2>可能的解决方案</h2>
<p>解决这个问题的一种方法是获取名称空间前缀,并将其添加到要查找的标记中。你可以用</p>
<pre><code>>>>> e.tag[:e.tag.index('}')+1]
'{http://www.openarchives.org/OAI/2.0/}'
</code></pre>
<p>在根元素<code>e</code>上查找名称空间,尽管我确信有更好的方法来完成此操作。在</p>
<p>现在,我们可以定义函数来提取我们想要的标记我们有一个可选的名称空间前缀:</p>
<pre><code>def findallNS(element, tag, namespace=None):
if namspace is not None:
return element.findall(namepsace+tag)
else:
return element.findall(tag)
def findNS(element, tag, namespace=None):
if namspace is not None:
return element.find(namepsace+tag)
else:
return element.find(tag)
</code></pre>
<p>所以现在我们可以写:</p>
<pre><code>>>> list_records = findNS(e, 'ListRecords', namespace)
>>> findallNS(list_records, 'record', namespace)
[<Element {http://www.openarchives.org/OAI/2.0/}record at 7f39ebf580e0>,
<Element {http://www.openarchives.org/OAI/2.0/}record at 7f39ebf58908>]
</code></pre>
<h2>替代方案</h2>
<p>另一种解决方案可能是编写一个函数来搜索以您感兴趣的标记结尾的所有标记,例如:</p>
<pre><code>def find_child_tags(element, tag):
return [child for child in element if child.tag.endswith(tag)]
</code></pre>
<p>这里根本不需要处理名称空间。在</p>