root/livinglogic.python.xist/src/ll/xist/scripts/xml2xsc.py @ 2987:5e8cdf51176a

Revision 2987:5e8cdf51176a, 3.7 KB (checked in by Walter Doerwald <walter@…>, 12 years ago)

Rename variable.

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4## Copyright 1999-2007 by LivingLogic AG, Bayreuth/Germany.
5## Copyright 1999-2007 by Walter Dörwald
6##
7## All Rights Reserved
8##
9## See xist/__init__.py for the license
10
11
12import sys, optparse
13
14from ll.xist import xsc, xnd, sims
15
16
17def iterpath(node):
18    yield [node]
19    if hasattr(node, "text") and node.text:
20        yield [node, node.text]
21    if hasattr(node, "getchildren"):
22        for child in node:
23            for path in iterpath(child):
24                yield [node] + path
25    if hasattr(node, "tail") and node.tail:
26        yield [node, node.tail]
27
28
29def getelementname(node):
30    xmlns = None
31    name = node.tag
32    if name.startswith("{"):
33        (xmlns, sep, name) = name[1:].partition("}")
34    return (name, xmlns)
35
36
37def etree2xnd(sims, node):
38    ns = xnd.Module()
39    elements = {} # maps (name, xmlns) to (xnd.Element, content set, attrname->xnd.Attr map)
40    procinsts = {} # maps name to xnd.ProcInst
41
42    for path in iterpath(node):
43        node = path[-1]
44        if "Element" in type(node).__name__:
45            (name, xmlns) = getelementname(node)
46            try:
47                entry = elements[(name, xmlns)]
48            except KeyError:
49                xndnode = xnd.Element(name, xmlns=xmlns)
50                entry = elements[(name, xmlns)] = (xndnode, set(), {})
51                ns(xndnode)
52            else:
53                xndnode = entry[0]
54            for attrname in node.keys():
55                if not attrname.startswith("{") and attrname not in entry[2]:
56                    attr = xnd.Attr(attrname, type=xsc.TextAttr)
57                    entry[0](attr)
58                    entry[2][attrname] = attr
59        elif "ProcessingInstruction" in type(node).__name__:
60            name = node.target
61            try:
62                xndnode = procinsts[name]
63            except KeyError:
64                procinst = xnd.ProcInst(name)
65                procinsts[name] = procinst
66                xndnode = procinst
67            ns(xndnode)
68        elif "Comment" in type(node).__name__:
69            xndnode = "#comment"
70        elif isinstance(node, basestring):
71            if node.isspace():
72                xndnode = "#whitespace"
73            else:
74                xndnode = "#text"
75        if len(path) >= 2:
76            parent = path[-2]
77            if "Element" in type(parent).__name__:
78                parententry = elements[getelementname(parent)]
79                parententry[1].add(xndnode)
80
81    # Put sims info into the element definitions
82    if sims == "none":
83        pass
84    elif sims == "simple":
85        for entry in elements.itervalues():
86            entry[0].modeltype = bool(entry[1])
87    elif sims == "full":
88        for entry in elements.itervalues():
89            if not entry[1]:
90                entry[0].modeltype = "sims.Empty"
91            else:
92                elements = [el for el in entry[1] if isinstance(el, xnd.Element)]
93                if not elements:
94                    if "#text" in entry[1]:
95                        entry[0].modeltype = "sims.NoElements"
96                    else:
97                        entry[0].modeltype = "sims.NoElementsOrText"
98                else:
99                    if "#text" in entry[1]:
100                        entry[0].modeltype = "sims.ElementsOrText"
101                    else:
102                        entry[0].modeltype = "sims.Elements"
103                    entry[0].modelargs = elements
104    else:
105        raise ValueError("unknown sims mode %r" % sims)
106    return ns
107
108
109def stream2xnd(stream, sims="simple", parser="etree"):
110    if parser == "etree":
111        from xml.etree import cElementTree
112        node = cElementTree.parse(stream).getroot()
113    elif parser == "lxml":
114        from lxml import etree
115        node = etree.parse(stream).getroot()
116    else:
117        raise ValueError("unknown parser %r" % parser)
118   
119    return etree2xnd(sims, node)
120
121
122def main():
123    p = optparse.OptionParser(usage="usage: %prog [options] <input.xml >output.py")
124    p.add_option("-p", "--parser", dest="parser", help="parser module to use for XML parsing (etree or lxml)", choices=("etree", "lxml"), default="etree")
125    choices = ["none", "simple", "full"]
126    p.add_option("-s", "--sims", dest="sims", help="Create sims info? (%s)" % ", ".join(choices), metavar="MODE", default="simple")
127
128    (options, args) = p.parse_args()
129    if len(args) != 0:
130        p.error("incorrect number of arguments")
131        return 1
132    print stream2xnd(sys.stdin, sims=options.sims, parser=options.parser).aspy()
133
134
135if __name__ == "__main__":
136    sys.exit(main())
Note: See TracBrowser for help on using the browser.