OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python -u |
| 2 # |
| 3 # The exercise of rewriting xsltproc on top of the python |
| 4 # bindings, not complete yet and shows up the things missing |
| 5 # from the existing python interfaces |
| 6 # |
| 7 import sys |
| 8 import time |
| 9 import os |
| 10 import string |
| 11 import libxml2 |
| 12 # Memory debug specific |
| 13 libxml2.debugMemory(1) |
| 14 import libxslt |
| 15 |
| 16 debug = 0 |
| 17 repeat = 0 |
| 18 timing = 0 |
| 19 novalid = 0 |
| 20 noout = 0 |
| 21 docbook = 0 |
| 22 html = 0 |
| 23 xinclude = 0 |
| 24 profile = 0 |
| 25 params = {} |
| 26 output = None |
| 27 errorno = 0 |
| 28 |
| 29 # |
| 30 # timing |
| 31 # |
| 32 begin = 0 |
| 33 endtime = 0 |
| 34 def startTimer(): |
| 35 global begin |
| 36 |
| 37 begin = time.time() |
| 38 |
| 39 def endTimer(msg): |
| 40 global begin |
| 41 global endtime |
| 42 |
| 43 endtime = time.time() |
| 44 print "%s took %d ms" % (msg, (endtime - begin) * 1000) |
| 45 |
| 46 def xsltProcess(doc, cur, filename): |
| 47 global timing |
| 48 global xinclude |
| 49 global params |
| 50 global html |
| 51 |
| 52 if xinclude: |
| 53 if timing: |
| 54 startTimer() |
| 55 doc.XIncludeProcess() |
| 56 if timing: |
| 57 endTimer("XInclude processing %s" % (filename)) |
| 58 |
| 59 if timing: |
| 60 startTimer() |
| 61 if output == None: |
| 62 if repeat != 0: |
| 63 for j in range(1, repeat): |
| 64 res = cur.applyStylesheet(doc, params) |
| 65 res.freeDoc() |
| 66 doc.freeDoc() |
| 67 if html == 1: |
| 68 doc = libxml2.htmlParseFile(filename, None) |
| 69 else: |
| 70 doc = libxml2.parseFile(filename, None) |
| 71 # ctxt = libxslt.newTransformContext(doc) |
| 72 # if ctxt == None: |
| 73 # return |
| 74 if profile: |
| 75 print "TODO: Profiling not yet supported" |
| 76 else: |
| 77 res = cur.applyStylesheet(doc, params) |
| 78 if timing: |
| 79 if repeat != 0: |
| 80 endTimer("Applying stylesheet %d times" % (repeat)) |
| 81 else: |
| 82 endTimer("Applying stylesheet") |
| 83 doc.freeDoc() |
| 84 if res == None: |
| 85 print "no result for %s" % (filename) |
| 86 return |
| 87 if noout != 0: |
| 88 res.freeDoc() |
| 89 return |
| 90 if debug == 1: |
| 91 res.debugDumpDocument(None) |
| 92 else: |
| 93 if timing: |
| 94 startTimer() |
| 95 cur.saveResultToFilename("-", res, 0) |
| 96 if timing: |
| 97 endTimer("Saving result") |
| 98 res.freeDoc() |
| 99 else: |
| 100 print "TODO: xsltRunStylesheet not yet mapped" |
| 101 |
| 102 def usage(name = 'pyxsltproc'): |
| 103 print "Usage: %s [options] stylesheet file [file ...]" % (name) |
| 104 print "a reimplementation of xsltproc(1) on top of libxslt-python" |
| 105 print " Options:" |
| 106 print "\t--version or -V: show the version of libxml and libxslt used" |
| 107 print "\t--verbose or -v: show logs of what's happening" |
| 108 print "\t--output file or -o file: save to a given file" |
| 109 print "\t--timing: display the time used" |
| 110 print "\t--repeat: run the transformation 20 times" |
| 111 print "\t--debug: dump the tree of the result instead" |
| 112 print "\t--novalid skip the Dtd loading phase" |
| 113 print "\t--noout: do not dump the result" |
| 114 print "\t--maxdepth val : increase the maximum depth" |
| 115 print "\t--html: the input document is(are) an HTML file(s)" |
| 116 print "\t--param name value : pass a (parameter,value) pair" |
| 117 print "\t value is an XPath expression." |
| 118 print "\t string values must be quoted like \"'string'\"" |
| 119 print "\t or use stringparam to avoid it" |
| 120 print "\t--stringparam name value : pass a (parameter,string value) pair" |
| 121 print "\t--nonet refuse to fetch DTDs or entities over network" |
| 122 print "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES" |
| 123 print "\t otherwise XML Catalogs starting from " |
| 124 print "\t file:///etc/xml/catalog are activated by default" |
| 125 print "\t--xinclude : do XInclude processing on document input" |
| 126 print "\t--profile or --norman : dump profiling informations " |
| 127 print "\nProject libxslt home page: http://xmlsoft.org/XSLT/" |
| 128 print "To report bugs and get help: http://xmlsoft.org/XSLT/bugs.html" |
| 129 |
| 130 def main(args = None): |
| 131 global debug |
| 132 global repeat |
| 133 global timing |
| 134 global novalid |
| 135 global noout |
| 136 global docbook |
| 137 global html |
| 138 global xinclude |
| 139 global profile |
| 140 global params |
| 141 global output |
| 142 global errorno |
| 143 |
| 144 done = 0 |
| 145 cur = None |
| 146 |
| 147 if not args: |
| 148 args = sys.argv[1:] |
| 149 if len(args) <= 0: |
| 150 usage(sys.argv[0]) |
| 151 |
| 152 |
| 153 i = 0 |
| 154 while i < len(args): |
| 155 if args[i] == "-": |
| 156 break |
| 157 if args[i][0] != '-': |
| 158 i = i + 1 |
| 159 continue |
| 160 if args[i] == "-timing" or args[i] == "--timing": |
| 161 timing = 1 |
| 162 elif args[i] == "-debug" or args[i] == "--debug": |
| 163 debug = 1 |
| 164 elif args[i] == "-verbose" or args[i] == "--verbose" or \ |
| 165 args[i] == "-v": |
| 166 print "TODO: xsltSetGenericDebugFunc() mapping missing" |
| 167 elif args[i] == "-version" or args[i] == "--version" or \ |
| 168 args[i] == "-V": |
| 169 print "TODO: version informations mapping missing" |
| 170 elif args[i] == "-verbose" or args[i] == "--verbose" or \ |
| 171 args[i] == "-v": |
| 172 if repeat == 0: |
| 173 repeat = 20 |
| 174 else: |
| 175 repeat = 100 |
| 176 elif args[i] == "-novalid" or args[i] == "--novalid": |
| 177 print "TODO: xmlLoadExtDtdDefaultValue mapping missing" |
| 178 novalid = 1 |
| 179 elif args[i] == "-noout" or args[i] == "--noout": |
| 180 noout = 1 |
| 181 elif args[i] == "-html" or args[i] == "--html": |
| 182 html = 1 |
| 183 elif args[i] == "-nonet" or args[i] == "--nonet": |
| 184 print "TODO: xmlSetExternalEntityLoader mapping missing" |
| 185 nonet = 1 |
| 186 elif args[i] == "-catalogs" or args[i] == "--catalogs": |
| 187 try: |
| 188 catalogs = os.environ['SGML_CATALOG_FILES'] |
| 189 except: |
| 190 catalogs = None |
| 191 if catalogs != none: |
| 192 libxml2.xmlLoadCatalogs(catalogs) |
| 193 else: |
| 194 print "Variable $SGML_CATALOG_FILES not set" |
| 195 elif args[i] == "-xinclude" or args[i] == "--xinclude": |
| 196 xinclude = 1 |
| 197 libxslt.setXIncludeDefault(1) |
| 198 elif args[i] == "-param" or args[i] == "--param": |
| 199 i = i + 1 |
| 200 params[args[i]] = args[i + 1] |
| 201 i = i + 1 |
| 202 elif args[i] == "-stringparam" or args[i] == "--stringparam": |
| 203 i = i + 1 |
| 204 params[args[i]] = "'%s'" % (args[i + 1]) |
| 205 i = i + 1 |
| 206 elif args[i] == "-maxdepth" or args[i] == "--maxdepth": |
| 207 print "TODO: xsltMaxDepth mapping missing" |
| 208 else: |
| 209 print "Unknown option %s" % (args[i]) |
| 210 usage() |
| 211 return(3) |
| 212 |
| 213 |
| 214 |
| 215 |
| 216 i = i + 1 |
| 217 |
| 218 libxml2.lineNumbersDefault(1) |
| 219 libxml2.substituteEntitiesDefault(1) |
| 220 # TODO: xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS |
| 221 # if novalid: |
| 222 # TODO: xmlLoadExtDtdDefaultValue = 0 |
| 223 |
| 224 # TODO libxslt.exsltRegisterAll(); |
| 225 libxslt.registerTestModule() |
| 226 |
| 227 i = 0 |
| 228 while i < len(args) and done == 0: |
| 229 if args[i] == "-maxdepth" or args[i] == "--maxdepth": |
| 230 i = i + 2 |
| 231 continue |
| 232 if args[i] == "-o" or args[i] == "-output" or args[i] == "--output": |
| 233 i = i + 2 |
| 234 continue |
| 235 if args[i] == "-param" or args[i] == "--param": |
| 236 i = i + 3 |
| 237 continue |
| 238 if args[i] == "-stringparam" or args[i] == "--stringparam": |
| 239 i = i + 3 |
| 240 continue |
| 241 if args[i] != "-" and args[i][0] == '-': |
| 242 i = i + 1 |
| 243 continue |
| 244 if timing: |
| 245 startTimer() |
| 246 style = libxml2.parseFile(args[i]) |
| 247 if timing: |
| 248 endTimer("Parsing stylesheet %s" % (args[i])) |
| 249 if style == None: |
| 250 print "cannot parse %s" % (args[i]) |
| 251 cur = None |
| 252 errorno = 4 |
| 253 done = 1 |
| 254 else: |
| 255 cur = libxslt.loadStylesheetPI(style) |
| 256 if cur != None: |
| 257 xsltProcess(style, cur, args[i]) |
| 258 cur = None |
| 259 else: |
| 260 cur = libxslt.parseStylesheetDoc(style) |
| 261 if cur == None: |
| 262 style.freeDoc() |
| 263 errorno = 5 |
| 264 done = 1 |
| 265 i = i + 1 |
| 266 break |
| 267 |
| 268 while i < len(args) and done == 0 and cur != None: |
| 269 if timing: |
| 270 startTimer() |
| 271 if html: |
| 272 doc = libxml2.htmlParseFile(args[i], None) |
| 273 else: |
| 274 doc = libxml2.parseFile(args[i]) |
| 275 if doc == None: |
| 276 print "unable to parse %s" % (args[i]) |
| 277 errorno = 6 |
| 278 i = i + 1 |
| 279 continue |
| 280 if timing: |
| 281 endTimer("Parsing document %s" % (args[i])) |
| 282 xsltProcess(doc, cur, args[i]) |
| 283 i = i + 1 |
| 284 |
| 285 if cur != None: |
| 286 cur.freeStylesheet() |
| 287 params = None |
| 288 |
| 289 if __name__ == "__main__": |
| 290 main() |
| 291 |
| 292 # Memory debug specific |
| 293 libxslt.cleanup() |
| 294 if libxml2.debugMemory(1) != 0: |
| 295 print "Memory leak %d bytes" % (libxml2.debugMemory(1)) |
| 296 libxml2.dumpMemory() |
| 297 |
| 298 sys.exit(errorno) |
OLD | NEW |