Python 扩展pyyaml以查找和替换xml元素树

Python 扩展pyyaml以查找和替换xml元素树,python,xml,yaml,elementtree,pyyaml,Python,Xml,Yaml,Elementtree,Pyyaml,我想扩展到处理一个非平凡的用例 Background:pyyaml非常可爱,因为它吃了YAML并破坏了Python本机数据结构。但是如果您想在YAML中找到一个特定的节点,该怎么办?引用的问题表明,嘿,您只知道节点在数据结构中的位置,并将其索引到其中。事实上,几乎所有关于皮亚姆问题的答案似乎都给出了同样的建议 但如果您事先不知道节点在YAML中的位置,该怎么办? 如果我使用XML,我会使用XML.etree.ElementTree解决这个问题。它们为将XML文档加载到内存和基于特定搜索条件查找元

我想扩展到处理一个非平凡的用例

Background:pyyaml非常可爱,因为它吃了YAML并破坏了Python本机数据结构。但是如果您想在YAML中找到一个特定的节点,该怎么办?引用的问题表明,嘿,您只知道节点在数据结构中的位置,并将其索引到其中。事实上,几乎所有关于皮亚姆问题的答案似乎都给出了同样的建议

但如果您事先不知道节点在YAML中的位置,该怎么办?

如果我使用XML,我会使用
XML.etree.ElementTree
解决这个问题。它们为将XML文档加载到内存和基于特定搜索条件查找元素提供了很好的工具。见和

问题:

  • pyyaml是否提供类似于ElementTree的搜索功能?(如果是的话,请随意对我大喊大叫,因为我不擅长谷歌。)
  • 如果没有,是否有人有很好的方法来扩展pyyaml以实现类似的事情?(没有再次遍历反序列化YAML的额外点数。)

  • 注意除了能够找到东西之外,ElementTree还提供了一个重要功能,即在给定元素引用的情况下修改XML文档。我也希望能够在YAML上执行此操作。

    您知道如何搜索python对象吗?然后您就知道如何搜索
    yaml.load()的结果了。

    YAML在两个重要方面与XML不同:一个是,虽然XML中的每个元素都有一个标记和一个值,但在YAML中,有些东西可能只是值。但是第二。。。同样,YAML创建python对象。内存中没有中间格式可供使用

    例如,如果像这样加载YAML文件:

    - First
    - Second
    - Third
    
    您将得到一个类似于
    ['First'、'Second'、'Third']
    的列表。想找到“第三个”,但不知道它在哪里?您可以使用
    [x代表我的\u列表中的x,如果x中的“第三个”
    来查找它。需要在字典中查找项目吗?就这么做吧

    如果要修改对象,则不修改YAML,而是修改对象。现在我希望第二个条目是德语。我只是做了
    “我的列表[1]=”茨威特“
    ,在适当的地方修改它。现在python列表看起来像
    ['First'、'zweite'、'Third']
    ,将其转储到YAML看起来像

    - First
    - zweite
    - Third
    
    请注意,Pyaml非常聪明。。。甚至可以使用循环创建对象:

    >>> a = [1,2,3]
    >>> b = {}
    >>> b[1] = a
    >>> b[2] = a
    >>> print yaml.dump(b)
    1: &id001 [1, 2, 3]
    2: *id001
    >>> b[2] = [3,4,5]
    >>> print yaml.dump(b)
    1: [1, 2, 3]
    2: [3, 4, 5]
    
    在第一种情况下,它甚至发现
    b[1]
    b[2]
    指向同一个对象,因此它创建了链接并自动将一个链接从一个链接放到另一个。。。在原始对象中,如果执行类似于
    a.pop()
    的操作,则
    b[1]
    b[2]
    都将显示一个条目已消失。如果您将该对象发送到YAML,然后将其重新加载,则仍然是这样

    (请注意,在第二个例子中,它们并不相同,PyYAML不创建额外的符号,因为它不需要)


    简言之:很可能你只是想得太多了

    问题1的答案是:否。PyYAML实现了YAML 1.1语言标准,没有任何关于通过标准或库中的任何路径查找标量的内容

    但是,如果安全地加载YAML结构,则所有内容都是映射、序列或标量。即使如此简单的表示法(与使用
    !typemarkers
    )的完全对象实例化相比,也可以包含递归自引用结构:

    &a x: *a 
    
    如果没有外部语义解释,这在XML中是不可能的。这使得在YAML中创建泛型树遍历器比在XML中困难得多。 YAML的类型加载机制也使得泛型树遍历变得更加困难,即使排除了自引用的问题

    如果您事先不知道节点的位置,那么您仍然需要知道如何识别节点,并且由于您不知道如何遍历父节点(可能在组合映射和序列的多个层中表示),因此几乎可以使用依赖于上下文的通用机制

    在不依赖上下文(通常)的情况下,剩下的是一个唯一可识别的值(如HTML
    id
    属性)。如果YAML中的所有对象都有这样一个唯一的id,那么就可以在(安全加载的)树中搜索这样一个id值,并提取它下面的任何结构(映射、序列)直到你碰到一个叶子(标量),或者某个有自己id的结构(另一个对象)


    我关注YAML开发已经有相当一段时间了(我在YAML文件夹中的YAML邮件列表中最早的电子邮件是从2004年开始的)从那以后,我再也没有看到任何泛型的发展。我确实有一些工具来遍历树,找到我用来提取简化结构部分以测试我的库的东西,但没有任何代码是可发布的(如果是的话,它应该已经在PyPI上了),并且没有任何类似于XML的通用解决方案(它本身就是IMO,语法上比YAML简单).

    您似乎假设从YAML文件加载的所有对象都是列表或DICT,而不是可能未定义迭代的更复杂的对象。因此,只有安全加载YAML并丢弃YAML文件中最有趣的细节(要加载的对象)时,您的假设才成立在这样做的时候。在加载它之前,您似乎必须了解一些关于该格式的信息,但是……这与调用其他未知API并获取某种未知格式和深度的对象没有什么不同。一般来说,正如您所说,python对象可以表示比可以重新定义的对象更丰富、更广泛的关联集以XML表示…所有XML值都是字符串,例如w