Source code for soapbox.xsd2py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
################################################################################

'''
'''

################################################################################
# Imports


import argparse
import hashlib
import keyword
import logging
import textwrap

from jinja2 import Environment, PackageLoader
from lxml import etree

from .xsdspec import Schema
from .utils import (
    capitalize,
    find_xsd_namespaces,
    get_get_type,
    open_document,
    remove_namespace,
    url_template,
    use,
)

try:
    from logging import NullHandler
except ImportError:
    from .compat import NullHandler


################################################################################
# Constants


TEMPLATE_PACKAGE = 'soapbox.templates'


################################################################################
# Globals


logger = logging.getLogger('soapbox')
logger.addHandler(NullHandler())


################################################################################
# Helpers


[docs]def get_rendering_environment(): ''' ''' pkg = TEMPLATE_PACKAGE.split('.') env = Environment( extensions=['jinja2.ext.loopcontrols'], loader=PackageLoader(*pkg), ) env.filters['capitalize'] = capitalize env.filters['remove_namespace'] = remove_namespace env.filters['url_template'] = url_template env.filters['use'] = use env.globals['keywords'] = keyword.kwlist env.globals['resolve_import'] = resolve_import env.globals['schema_name'] = schema_name return env
[docs]def resolve_import(xsdimport, known_namespaces): ''' ''' logger.info('Generating code for XSD import \'%s\'...' % xsdimport.schemaLocation) xml = open_document(xsdimport.schemaLocation) xmlelement = etree.fromstring(xml) return generate_code_from_xsd(xmlelement, known_namespaces, xsdimport.schemaLocation)
[docs]def schema_name(namespace): ''' ''' return hashlib.sha512(namespace).hexdigest()[0:5]
[docs]def generate_code_from_xsd(xmlelement, known_namespaces=None, location=None): ''' ''' if known_namespaces is None: known_namespaces = [] xsd_namespace = find_xsd_namespaces(xmlelement.nsmap) schema = Schema.parse_xmlelement(xmlelement) # Skip if this schema has already been included: if schema.targetNamespace in known_namespaces: return '' return schema_to_py(schema, xsd_namespace, known_namespaces, location)
[docs]def schema_to_py(schema, xsd_namespace, known_namespaces=None, location=None): ''' ''' if known_namespaces is None: known_namespaces = [] known_namespaces.append(schema.targetNamespace) env = get_rendering_environment() env.filters['type'] = get_get_type(xsd_namespace) env.globals['known_namespaces'] = known_namespaces env.globals['location'] = location tpl = env.get_template('xsd') return tpl.render(schema=schema) ################################################################################ # Program
[docs]def parse_arguments(): ''' ''' parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent('''\ Generates Python code from an XSD document. ''')) parser.add_argument('xsd', help='The path to an XSD document.') return parser.parse_args()
[docs]def main(): ''' ''' opt = parse_arguments() logger.info('Generating code for XSD document \'%s\'...' % opt.xsd) xml = open_document(opt.xsd) xmlelement = etree.fromstring(xml) print textwrap.dedent('''\ from soapbox import xsd from soapbox.xsd import UNBOUNDED ''') print generate_code_from_xsd(xmlelement)
if __name__ == '__main__': main() ################################################################################ # vim:et:ft=python:nowrap:sts=4:sw=4:ts=4