在lxml解析函数中处理全局命名空间

时间:2016-07-07 18:57:12

标签: python xpath lxml

我正在处理一些共享自定义命名空间的XML文档。我有各种不同类型的文件具有相同的命名空间,并试图找出解析时处理命名空间的最佳/最优雅的方式。这是一个例子:

在特定脚本的开头,我读入一个XML文件,用etree.parse()解析它,检查第一个或第二个标签以识别命名空间,然后我将它们保存在某个地方。我可以将它们放在全局中但是现在它们作为self.ns存储在类级别。

我有这个函数,我写的是从给定的xpath查询返回值。它看起来像这样:

# noinspection PyBroadException
def get_value(self, lxml_object, xpath_query=None, return_int=False):
    """
    BE CAREFUL using this function because it will catch all xpath query exceptions
    :param lxml_object: an lxml.etree object
    :param xpath_query: a valid xpath query
    :param return_int: set to True if you want an int rather than a string
    :return: the value of the field corresponding to the xpath query
    """
    if return_int is True:
        if xpath_query:
            try:
                return int(lxml_object.xpath(xpath_query, namespaces=self.ns)[0].text)
            except:
                return None
        else:
            try:
                return int(lxml_object[0].text)
            except:
                return None
    else:
        if xpath_query:
            try:
                return lxml_object.xpath(xpath_query, namespaces=self.ns)[0].text
            except:
                return None
        else:
            try:
                return lxml_object[0].text
            except:
                return None

当我将它放入班级并致电self.get_value()时,这很好,因为已经定义了self.ns

我在很多不同的脚本中使用这个函数,并希望将它放在一个单独的文件中来解析实用程序,我可以从中导入它。然而,这引发了向它添加名称空间参数的幽灵,并且每次我使用它时都必须将名称空间传递给函数,例如

return get_value(some_lxml_object, 'some xpath query', ns=self.ns)

如果我不想每次调用函数时都要传递名称空间参数,我该如何构造所有这些?

1 个答案:

答案 0 :(得分:0)

你可以做的是"部分应用功能"。

def build_value_getter(namespace):
    def func(some_lxml_object, 'some xpath query', ns=namespace)
        return get_value(some_lxml_object, 'some xpath query', ns=ns)
    return func

my_get_value = build_value_getter(self.ns)
my_get_value(some_lxml_object, 'some xpath query') # Uses self.ns implicitly