9.5. 搜索元素

通过一步步访问每一个节点的方式遍历 XML 文档可能很乏味。如果你正在寻找些特别的东西,又恰恰它们深深埋入了你的 XML 文档,有个捷径让你可以快速找到它:getElementsByTagName

在这部分,将使用 binary.xml 语法文件,它的内容如下:

例 9.20. binary.xml

<?xml version="1.0"?>
<!DOCTYPE grammar PUBLIC "-//diveintopython.org//DTD Kant Generator Pro v1.0//EN" "kgp.dtd">
<grammar>
<ref id="bit">
  <p>0</p>
  <p>1</p>
</ref>
<ref id="byte">
  <p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\
<xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>
</ref>
</grammar>

它有两个 ref'bit' (位) 和 'byte' (字节)。一个 bit'0' 或者 '1',而一个 byte 是 8 个 bit

例 9.21. getElementsByTagName 介绍

>>> from xml.dom import minidom
>>> xmldoc = minidom.parse('binary.xml')
>>> reflist = xmldoc.getElementsByTagName('ref') 1
>>> reflist
[<DOM Element: ref at 136138108>, <DOM Element: ref at 136144292>]
>>> print reflist[0].toxml()
<ref id="bit">
  <p>0</p>
  <p>1</p>
</ref>
>>> print reflist[1].toxml()
<ref id="byte">
  <p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\
<xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>
</ref>
1 getElementsByTagName 接收一个参数,即要找的元素的名称。它返回一个 Element 对象的列表,列表中的对象都是有指定名称的 XML 元素。在本例中,你能找到两个 ref 元素。

例 9.22. 每个元素都是可搜索的

>>> firstref = reflist[0]                      1
>>> print firstref.toxml()
<ref id="bit">
  <p>0</p>
  <p>1</p>
</ref>
>>> plist = firstref.getElementsByTagName("p") 2
>>> plist
[<DOM Element: p at 136140116>, <DOM Element: p at 136142172>]
>>> print plist[0].toxml()                     3
<p>0</p>
>>> print plist[1].toxml()
<p>1</p>
1 继续前面的例子,在 reflist 中的第一个对象是 'bit' ref元素。
2 你可以在这个 Element 上使用相同的 getElementsByTagName 方法来寻找所有在'bit' ref 元素中的<p>元素。
3 和前面一样,getElementsByTagName 方法返回一个找到元素的列表。在本例中,你有两个元素,每“位”各占一个。

例 9.23. 搜索实际上是递归的

>>> plist = xmldoc.getElementsByTagName("p") 1
>>> plist
[<DOM Element: p at 136140116>, <DOM Element: p at 136142172>, <DOM Element: p at 136146124>]
>>> plist[0].toxml()                         2
'<p>0</p>'
>>> plist[1].toxml()
'<p>1</p>'
>>> plist[2].toxml()                         3
'<p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\
<xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>'
1 仔细注意这个例子和前面例子之间的不同。前面,你是在 firstref 中搜索 p 元素,但是这里你是在 xmldoc 中搜索 p 元素,xmldoc 是代表了整个 XML 文档的根层对象。这样就会 找到嵌套在 ref 元素 (它嵌套在根 grammar 元素中) 中的 p 元素。
2 前两个 p 元素在第一个 ref 内 ('bit' ref)。
3 后一个 p 元素在第二个 ref 中 ('byte' ref)。