root/livinglogic.python.xist/src/ll/xist/scripts/xml2xsc.py @ 3893:8ded7a61db60

Revision 3893:8ded7a61db60, 3.8 KB (checked in by Walter Doerwald <walter@…>, 10 years ago)

Use format method instead of % for string formatting. Optimize JSP for UL4 templates.

The generated JSP code for the UL4 function xmlescape no longer calls
ObjectUtils?.toString().

Use autoboxing in the Java code generated by jsp.fromul4().

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