【问题标题】:Python object wrapper for lxml etree?lxml etree的Python对象包装器?
【发布时间】:2011-05-11 15:28:10
【问题描述】:

给定 lxml.etree 是否有可能以某种方式构造树的对象表示,以便可以以类似对象的方式访问子元素(使用 '.' 运算符)?

我知道 lxml 有一个名为 objectify 的库,但它看起来只能在给定原始 XML 的情况下构建,并且向树中添加新元素仍然需要通过类似 etree 的节点创建。

理想情况下我想要实现的是:

tree = objectify( etree_root )
print tree.somenode.get( 'attrib_name' )
tree.somenode.set( 'attrib_name', 'some_val' )
Node( tree.somenode, "somechild" )
tree.somenode.somechild.set( 'attrib', 'foo' ) 

【问题讨论】:

    标签: python xml lxml


    【解决方案1】:

    我猜你必须分别覆盖 __setattribute____getattribute__ 运算符。我想你必须继承 etree.Element 类来实现这一点。

    但是,另一方面,这个 API 也很不切实际,因为可能有多个具有相同标签名称的子节点。

    要查找元素,您还可以使用与您的想法相关的 XPath 表达式。 API如下:

    subchild = root.find('child/subchild')
    

    【讨论】:

    • 并非完全不切实际。通过一些巧妙的修改,您可以使其对某些类型的数据有用。您可以覆盖__get_attribute__,如果引用node.childname,它将只返回第一个孩子,但对于`node.childnames(最后带有's'),它将返回它们的列表。这种设计是否真的有用取决于您的 XML 数据。
    • 感谢您的提示。这实际上比我想象的要容易。我设法在一个相当大的 XML 树(约 20 毫秒)中客观化了每个元素。这允许执行以下操作:root.child.nonexistentchild[ "attrib" ] = "hello" 这会即时创建nonexistentchild 并添加属性attrib 和值hello。只需要覆盖__setattr____getattr____get____set__。然后,您只需通过获取每个节点并为每个兄弟创建对象包装器来创建一个 objectified 树。
    • neat :) 是否有可能从某个地方获取代码?
    • 不,由于法律原因,恐怕我不能这样做。需要注意的一件事是序列。由于在对象化时您没有断言 XSD 模式,如果原始 XML 树中有一个元素,您无法知道它是否是序列的一部分。如果需要,您可以通过提供一种“转换”为序列的方法来解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2015-09-09
    • 1970-01-01
    • 2014-11-17
    相关资源
    最近更新 更多