Welcome, guest | Sign In | My Account | Store | Cart

Converts Python ASTs to XML files for reading in other languages.

Python, 59 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import ast, re, sys
from xml.dom import minidom

try:
    from xml.etree import cElementTree as etree
except:
    try:
        from lxml import etree
    except:
        from xml.etree import ElementTree as etree

def prettify(xml_string):
    reparsed = minidom.parseString(xml_string)
    return reparsed.toprettyxml(indent="  ") 

class ast2xml(ast.NodeVisitor):
    def __init__(self):
        super(ast.NodeVisitor, self).__init__()
        self.path = []
        self.root = etree.Element('ast')
        self.celement = self.root
        self.lname = 'module'
    def convert(self, tree):
        self.visit(tree)
        return etree.tostring(self.root)
    def generic_visit(self, node):
        self.path.append(type(node).__name__)
        ocelement = self.celement
        self.celement = etree.SubElement(self.celement, self.lname)
        self.celement.attrib.update({'_name': type(node).__name__})
        olname = self.lname
        self.lname = type(node).__name__
        for item in node.__dict__:
            self.lname = item
            if isinstance(getattr(node, item), ast.AST):
                self.generic_visit(getattr(node, item))
            elif isinstance(getattr(node, item), list):
                ocel2 = self.celement
                olname2 = self.lname
                self.celement = etree.SubElement(self.celement, self.lname)
                self.celement.attrib.update({'_name': '_list'})
                self.lname = '_list_element'
                [self.generic_visit(childnode) for childnode in getattr(node, item) if isinstance(childnode, (ast.AST, list))]
                self.celement = ocel2
                self.lname = olname2
            else:
                self.celement.attrib.update({item: str(getattr(node, item))})
        self.path.pop()
        self.celement = ocelement
        self.lname = olname

def main(fpath):
    with open(fpath, 'r') as f:
        tree = ast.parse(f.read())
        res = ast2xml().convert(tree)
        print prettify(res)

if __name__ == '__main__':
    main(sys.argv[1])

Converts a Python AST into an XML file.

Command line usage:

ast2xml.py <file>

Usage in another script:

import ast2xml
...
ast2xml.ast2xml().convert(ast_tree)