如何将 XML 转换为 python AST

Posted

技术标签:

【中文标题】如何将 XML 转换为 python AST【英文标题】:How To Convert XML to python AST 【发布时间】:2018-12-28 02:05:53 【问题描述】:

我希望有人可以帮助我在这里找到正确的资源。我在这个论坛和其他地方四处寻找,但我找不到合适的资源。 很抱歉没有把我的问题说得很清楚,所以让我用这个简单的例子来说明一下: 原始源代码:

    a='''
for x in y:
    print(x)
'''

这段代码的python AST树是:

tree_a=ast.parse(a)

这棵树的平面版本:

d=ast.dump(tree_a)

输出(d的内容):

"Module(body=[For(target=Name(id='x', ctx=Store()), iter=Name(id='y', ctx=Load()), body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Name(id='x', ctx=Load())], keywords=[]))], orelse=[])])"

使用此资源Python AST to XMLtree_a 可以转换为 XML 格式:

res_0 = ast2xml().convert(tree_a)
with open('tree_a.xml','w') as f:
    res1=f.write(str(prettify(res_0)))

'tree_a.xml'的内容是:

<?xml version="1.0" ?>
<ast>
  <Module>
    <body>
      <For col_offset="0" lineno="2">
        <Name col_offset="4" id="x" lineno="2">
          <Store/>
        </Name>
        <Name col_offset="9" id="y" lineno="2">
          <Load/>
        </Name>
        <body>
          <Expr col_offset="4" lineno="3">
            <Call col_offset="4" lineno="3">
              <Name col_offset="4" id="print" lineno="3">
                <Load/>
              </Name>
              <args>
                <Name col_offset="10" id="x" lineno="3">
                  <Load/>
                </Name>
              </args>
              <keywords/>
            </Call>
          </Expr>
        </body>
        <orelse/>
      </For>
    </body>
  </Module>
</ast>

拥有 xml 格式的树,我想对文件进行一些测试和修改,然后返回到 python AST 树,以便查看对实际源代码的影响。所以我的问题是:给定像'tree_a.xml'这样的xml文件,我如何将它转换为python AST树。 我的目标是最终回到原始源代码。但是,如果我有来自 xml 文件的 python AST 树,我可以这样做。 任何帮助表示赞赏。

【问题讨论】:

alpha5401 你有想过这个吗?我正在尝试做类似的事情 - 尝试编译和执行您的 'd=ast.dump(tree_a)' 生成的字符串。 【参考方案1】:

每个ast literal 包含一个_fields 属性,您可以使用该属性通过递归重建原始ast 对象:

import ast, xml.etree.ElementTree as ET
from itertools import zip_longest as zl
def to_ast(xml):
   if xml is None:
      return 
   if not hasattr(ast, xml.tag):
      return [to_ast(i) for i in xml]
   return (t:=getattr(ast, xml.tag))(**(k:=xml.attrib), 
          **a:to_ast(b) for a, b in zl([i for i in t._fields if i not in k], xml))

xml_tree = ET.parse('tree_a.xml')
new_ast = to_ast(list(xml_tree._root)[0])

您可以使用 ast.unparse(在 Python 3.9 中可用)检查由 to_ast 创建的新 ast 实例是否与原始实例匹配:

print(ast.unparse(new_ast))

输出:

for x in y: # type: 
    print(x)

【讨论】:

以上是关于如何将 XML 转换为 python AST的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义 AST 转换为 JS 代码

如何将 TypeScript 文件的对象文字 AST 转换为实际代码?

python中如何将字符串转换为字典

使用 Python 将 AST 形式的 Coq 术语转换为修饰符号

将List的String表示形式转换为Dictionary Python

如何将字符串转换为字典或列表?