代码之家  ›  专栏  ›  技术社区  ›  adamJLev

使lxml.objectify忽略XML命名空间?

  •  3
  • adamJLev  · 技术社区  · 14 年前

    所以我要处理一些像这样的XML:

    <ns2:foobarResponse xmlns:ns2="http://api.example.com">
      <duration>206</duration>
      <artist>
        <tracks>...</tracks>
      </artist>
    </ns2:foobarResponse>
    

    我找到了LXML objectify 模块,它允许您像字典一样,以一种蟒蛇式的方式遍历XML文档。
    问题是:每次您试图访问一个元素时,它都使用伪造的XML命名空间,如下所示:

    from lxml import objectify
    
    tree = objectify.fromstring(xml)
    print tree.artist
    # ERROR: no such child: {http://api.example.com}artist
    

    它试图进入 <artist> 使用父命名空间,但标记不使用ns。

    有什么办法可以避开这个吗?谢谢

    2 回复  |  直到 12 年前
        1
  •  7
  •   Jeffrey Harris    14 年前

    根据lxml.objectify documentation ,属性查找默认为使用其父元素的命名空间。

    你可能是什么 希望 工作将是:

    print tree["{}artist"]
    

    如果您的孩子有一个非空的名称空间(“),这样的qname语法就可以工作了。{ http://foo/ }例如,artist),但不幸的是,当前源代码将空命名空间视为 名称空间,所以所有Objectify的查找优缺点都将有助于将空名称空间替换为父名称空间,这样您就走运了。

    这要么是一个bug(“artist”应该工作),要么是LXML人员对文件的增强请求。

    目前,最好的办法可能是:

    print tree.xpath("artist")
    

    我不清楚在这里使用xpath会给性能带来多大的影响,但这确实有效。

        2
  •  3
  •   Holger    12 年前

    仅供参考:请注意,这是自LXML 2.3以来预期的工作方式。

    从lxml更改日志:

    “ […]

    2.3(2011-02-06)新增功能

    • 查找子级时,lxml.objectify将“tag”作为含义 空命名空间,而不是父命名空间。

    […]

    行动中:

    >>> xml = """<ns2:foobarResponse xmlns:ns2="http://api.example.com">
    ...   <duration>206</duration>
    ...   <artist>
    ...     <tracks>...</tracks>
    ...   </artist>
    ... </ns2:foobarResponse>"""
    >>> tree = objectify.fromstring(xml)
    >>> print tree['{}artist']
    artist = None [ObjectifiedElement]
        tracks = '...' [StringElement]
    >>>