2

我有一些使用 lxml 处理的标记数据。当我打开一个文件时,在打开文件之前我不知道我是否有三种类型的元素中的一种或多种(我可能有一种、两种或三种不同的元素以及我拥有的任何类型的多个实例)

我需要一些关于这些元素的信息,这些信息包含在元素的子标签中

<element_type_1>
        <name>joe smith</name>
</element_type_1>
<element_type_2>
        <name>mary smith</name>
</element_type_2>
<element_type_3>
        <name>patrick smith</name>
</element_type_3>

因此,在这种情况下,我拥有所有三种类型,但每种类型只有一种,但是任何类型的任意数量都可能很大。

我通过cssselect在我的函数中使用 3 次来获取元素

def get_types(myTree):
    type_dict=defaultdict(list)
    type_dict['type_1']=myTree.cssselect('element_type_1')
    type_dict['type_2']=myTree.cssselect('element_type_2')
    type_dict['type_3']=myTree.cssselect('element_type_3')
    ret type_dict

这似乎过于多余

我是否错过了一些可以清理这个问题的东西?

仅供参考,我这样做是因为对于每种类型,我都必须匹配相关文档中的一些其他数据

早期的答案表明我需要澄清一下 - 我想避免三次穿过树

4

4 回答 4

5

你可以这样做:

for i in range(1, 4):
    type_dict['type_%d' % i] = myTree.cssselect('element_type_%d' % i)
于 2012-07-29T21:16:27.707 回答
1

取决于你是否知道它的外观。使用变量作为键可能是一件简单的事情,可以帮助您稍微改进它。

def get_types(myTree):
    type_dict=defaultdict(list)
    for i in range(1,4):
      x = 'type_%d' % i
      y = 'element_type_%d' % i
      type_dict[x] = myTree.csselect(y)
    return type_dict
于 2012-07-29T21:16:21.863 回答
1

如果您事先不知道它们的名称,我不知道您如何识别这些“类型”。他们是否遵循一些您可以搜索的固定模式?

例如,您可以执行以下操作:

d = {}
typeelements = "*[starts-with(local-name(), 'element_type_')]"
for e in myTree.xpath(typeelements)
    typename = e.tag.split('_',1)[1]
    d[typename] = e

或者更简洁地说:

d = {e.tag.split('_',1)[1]:e for e in myTree.xpath(typeelements)}

或者,您可以根据元素本身的某些条件来选择元素。IUn你的例子他们都有name孩子,所以你可以使用这样的路径:

typeelements = '*[name]'

或者您可以结合这两个要求:

typeelements = "*[starts-with(name(), 'element_type_')][name]"
于 2012-09-27T22:00:21.893 回答
0

或者您可以遍历一组已知标签以查找匹配元素。当你找到一个元素时,将 (tag, value) 添加到字典中。应该可以正常工作。

于 2012-07-29T21:42:13.453 回答