您在这里:首页 > 深入 Python > 脚本和流 > 缓存节点查找 | << >> | ||||
深入 Python从 Python 新手到专家 |
kgp.py 采用了几种技巧,这些技巧在您的 XML 处理中可能有用,也可能没用。第一个技巧利用输入文档的一致结构来构建节点缓存。
语法文件定义了一系列 ref 元素。每个 ref 元素包含一个或多个 p 元素,这些元素可以包含许多不同的内容,包括 xref。每当您遇到 xref 时,您都需要查找具有相同 id 属性的对应 ref 元素,并选择该 ref 元素的其中一个子元素并对其进行解析。(您将在下一节中看到如何进行这种随机选择。)
您可以通过以下方式构建语法:为最小的部分定义 ref 元素,然后通过使用 xref 定义“包含”第一个 ref 元素的 ref 元素,依此类推。然后,您解析“最大”的引用并跟随每个 xref,最终输出真实的文本。您输出的文本取决于您每次填充 xref 时做出的(随机)决定,因此每次输出都不同。
这非常灵活,但有一个缺点:性能。当您找到一个 xref 并需要找到具有相同 id 属性的 ref 元素时,您就会遇到问题。xref 有一个 id 属性,您想找到具有相同 id 属性的 ref 元素,但没有简单的方法可以做到这一点。缓慢的方法是每次都获取 ref 元素的完整列表,然后手动循环并查看每个 id 属性。快速的方法是只做一次,并以字典的形式构建一个缓存。
def loadGrammar(self, grammar): self.grammar = self._load(grammar) self.refs = {}for ref in self.grammar.getElementsByTagName("ref"):
self.refs[ref.attributes["id"].value] = ref
![]()
![]() |
首先创建一个空字典 self.refs。 |
![]() |
正如您在9.5 节“搜索元素”中看到的,getElementsByTagName 返回特定名称的所有元素的列表。您可以轻松地获取所有 ref 元素的列表,然后只需循环遍历该列表即可。 |
![]() |
正如您在9.6 节“访问元素属性”中看到的,您可以使用标准字典语法按名称访问元素的各个属性。因此,self.refs 字典的键将是每个 ref 元素的 id 属性的值。 |
![]() |
self.refs 字典的值将是 ref 元素本身。正如您在9.3 节“解析 XML”中看到的,解析后的 XML 文档中的每个元素、每个节点、每个注释、每段文本都是一个对象。 |
构建此缓存后,每当您遇到 xref 并需要找到具有相同 id 属性的 ref 元素时,您只需在 self.refs 中查找即可。
def do_xref(self, node): id = node.attributes["id"].value self.parse(self.randomChildElement(self.refs[id]))
您将在下一节中探索 randomChildElement 函数。
<< 标准输入、输出和错误 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
查找节点的直接子节点 >> |