Python 扩展pyyaml以查找和替换xml元素树
我想扩展到处理一个非平凡的用例 Background:pyyaml非常可爱,因为它吃了YAML并破坏了Python本机数据结构。但是如果您想在YAML中找到一个特定的节点,该怎么办?引用的问题表明,嘿,您只知道节点在数据结构中的位置,并将其索引到其中。事实上,几乎所有关于皮亚姆问题的答案似乎都给出了同样的建议 但如果您事先不知道节点在YAML中的位置,该怎么办? 如果我使用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文档加载到内存和基于特定搜索条件查找元
XML.etree.ElementTree
解决这个问题。它们为将XML文档加载到内存和基于特定搜索条件查找元素提供了很好的工具。见和
问题:
注意除了能够找到东西之外,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的类型加载机制也使得泛型树遍历变得更加困难,即使排除了自引用的问题
如果您事先不知道节点的位置,那么您仍然需要知道如何识别节点,并且由于您不知道如何遍历父节点(可能在组合映射和序列的多个层中表示),因此几乎可以使用依赖于上下文的通用机制
在不依赖上下文(通常)的情况下,剩下的是一个唯一可识别的值(如HTMLid
属性)。如果YAML中的所有对象都有这样一个唯一的id,那么就可以在(安全加载的)树中搜索这样一个id值,并提取它下面的任何结构(映射、序列)直到你碰到一个叶子(标量),或者某个有自己id的结构(另一个对象)
我关注YAML开发已经有相当一段时间了(我在YAML文件夹中的YAML邮件列表中最早的电子邮件是从2004年开始的)从那以后,我再也没有看到任何泛型的发展。我确实有一些工具来遍历树,找到我用来提取简化结构部分以测试我的库的东西,但没有任何代码是可发布的(如果是的话,它应该已经在PyPI上了),并且没有任何类似于XML的通用解决方案(它本身就是IMO,语法上比YAML简单).您似乎假设从YAML文件加载的所有对象都是列表或DICT,而不是可能未定义迭代的更复杂的对象。因此,只有安全加载YAML并丢弃YAML文件中最有趣的细节(要加载的对象)时,您的假设才成立在这样做的时候。在加载它之前,您似乎必须了解一些关于该格式的信息,但是……这与调用其他未知API并获取某种未知格式和深度的对象没有什么不同。一般来说,正如您所说,python对象可以表示比可以重新定义的对象更丰富、更广泛的关联集以XML表示…所有XML值都是字符串,例如w