10.4. 查找节点的直接子节点
Description: Python from novice to pro
Keywords: Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free

# 深入 Python :Dive Into Python 中文版 Python 从新手到专家 [Dip_5.4b_CPyUG_Release] | Find:

## 10.4. 查找节点的直接子节点

解析 XML 文档时，另一个有用的己技巧是查找某个特定元素的所有直接子元素。例如，在语法文件中，一个 `ref` 元素可以有数个 `p` 元素，其中每一个都可以包含很多东西，包括其他的 `p` 元素。你只要查找作为 `ref` 孩子的 `p` 元素，不用查找其他 `p` 元素的孩子 `p` 元素。

你可能认为你只要简单地使用 `getElementsByTagName` 来实现这点就可以了，但是你不可以这么做。`getElementsByTagName` 递归搜索并返回所有找到的元素的单个列表。由于 `p` 元素可以包含其他的 `p` 元素，你不能使用 `getElementsByTagName`，因为它会返回你不要的嵌套 `p` 元素。为了只找到直接子元素，你要自己进行处理。

### 例 10.16. 查找直接子元素

        def randomChildElement(self, node):
            choices = [e for e in node.childNodes
                       if e.nodeType == e.ELEMENT_NODE]
            chosen = random.choice(choices)
            return chosen

| 正如你在例 9.9 “获取子节点”中看到的，`childNodes` 属性返回元素所有子节点的一个列表。
| 然而，正如你在例 9.11 “子节点可以是文本”中看到的，`childNodes` 返回的列表包含了所有不同类型的节点，包括文本节点。这并不是你在这里要查找的。你只要元素形式的孩子。
| 每个节点都有一个 `nodeType` 属性，它可以是`ELEMENT_NODE`, `TEXT_NODE`, `COMMENT_NODE`，或者其它值。可能值的完整列表在 `xml.dom` 包的 `__init__.py` 文件中。(关于包的介绍，参见第 9.2 节 “包”。) 但你只是对元素节点有兴趣，所以你可以过滤出一个列表，其中只包含 `nodeType` 是`ELEMENT_NODE`的节点。
| 只要拥有了一个真实元素的列表，选择任意一个都很容易。Python 有一个叫 `random` 的模块，它包含了好几个有用的函数。`random.choice` 函数接收一个任意数量条目的列表并随机返回其中的一个条目。比如，如果 `ref` 元素包含了多个 `p` 元素，那么 `choices` 将会是 `p` 元素的一个列表，而 `chosen` 将被赋予其中的某一个值，而这个值是随机选择的。