def retrieve_schema_source(self, source): """ Returns a schema source that can be used to create an XMLSchema instance. :param source: A string or an ElementTree's Element. :return: An schema source string, an ElementTree's Element or a full pathname. """ if is_etree_element(source): if source.tag in (XSD_SCHEMA, 'schema'): return source elif get_namespace(source.tag): raise XMLSchemaValueError("source %r namespace has to be empty." % source) elif source.tag not in {'element', 'attribute', 'simpleType', 'complexType', 'group', 'attributeGroup', 'notation'}: raise XMLSchemaValueError("% is not an XSD global definition/declaration." % source) root = etree_element('schema', attrib={ 'xmlns:ns': "ns", 'xmlns': "http://www.w3.org/2001/XMLSchema", 'targetNamespace': "ns", 'elementFormDefault': "qualified", 'version': self.schema_class.XSD_VERSION, }) root.append(source) return root else: source = source.strip() if not source.startswith('<'): return self.casepath(source) else: return self.SCHEMA_TEMPLATE.format(self.schema_class.XSD_VERSION, source)
def __setattr__(self, name, value): """ :param name: attribute name. :param value: attribute value. :raises XMLSchemaValueError: Schema validation error for this converter """ if name in ('text_key', 'cdata_prefix') and value is not None: raise XMLSchemaValueError( 'Wrong value %r for the attribute %r of a %r.' % (value, name, type(self))) super(xmlschema.XMLSchemaConverter, self).__setattr__(name, value)
def xml2json(): parser = argparse.ArgumentParser( prog=PROGRAM_NAME, add_help=True, description="decode a set of XML files to JSON.") parser.usage = "%(prog)s [OPTION]... [FILE]...\n" \ "Try '%(prog)s --help' for more information." parser.add_argument('-v', dest='verbosity', action='count', default=0, help="increase output verbosity.") parser.add_argument('--schema', type=str, metavar='PATH', help="path or URL to an XSD schema.") parser.add_argument('--version', type=xsd_version_number, default='1.0', help="XSD schema validator to use (default is 1.0).") parser.add_argument('-L', dest='locations', nargs=2, type=str, action='append', metavar="URI/URL", help="schema location hint overrides.") parser.add_argument( '--converter', type=str, metavar='NAME', help="use a different XML to JSON convention instead of " "the default converter. Option value can be one of " "{!r}.".format(tuple(CONVERTERS_MAP))) parser.add_argument( '--lazy', action='store_true', default=False, help="use lazy decoding mode (slower but use less memory).") parser.add_argument( '-o', '--output', type=str, default='.', help="where to write the encoded XML files, current dir by default.") parser.add_argument('-f', '--force', action="store_true", default=False, help="do not prompt before overwriting.") parser.add_argument('files', metavar='[XML_FILE ...]', nargs='+', help="XML files to be decoded to JSON.") args = parser.parse_args() loglevel = get_loglevel(args.verbosity) schema_class = XMLSchema if args.version == '1.0' else XMLSchema11 converter = get_converter(args.converter) if args.schema is not None: schema = schema_class(args.schema, locations=args.locations, loglevel=loglevel) else: schema = None base_path = pathlib.Path(args.output) if not base_path.exists(): base_path.mkdir() elif not base_path.is_dir(): raise XMLSchemaValueError("{!r} is not a directory".format( str(base_path))) tot_errors = 0 for xml_path in map(pathlib.Path, args.files): json_path = base_path.joinpath(xml_path.name).with_suffix('.json') if json_path.exists() and not args.force: print("skip {}: the destination file exists!".format( str(json_path))) continue with open(str(json_path), 'w') as fp: try: errors = to_json( xml_document=str(xml_path), fp=fp, schema=schema, cls=schema_class, converter=converter, lazy=args.lazy, validation='lax', ) except (xmlschema.XMLSchemaException, URLError) as err: tot_errors += 1 print("error with {}: {}".format(str(xml_path), str(err))) continue else: if not errors: print("{} converted to {}".format(str(xml_path), str(json_path))) else: tot_errors += len(errors) print("{} converted to {} with {} errors".format( str(xml_path), str(json_path), len(errors))) sys.exit(tot_errors)
def check_value(value, *values): if value not in values: raise XMLSchemaValueError("wrong value %r, it must be one of %r." % (value, values))
def main(): parser = argparse.ArgumentParser( prog=PROGRAM_NAME, add_help=True, description="generate code for an XSD schema.") parser.usage = "%(prog)s [OPTION]... [FILE]...\n" \ "Try '%(prog)s --help' for more information." parser.add_argument('-v', dest='verbosity', action='count', default=0, help="increase output verbosity.") parser.add_argument('--schema', type=str, metavar='PATH', required=True, help="path or URL to an XSD schema.") parser.add_argument('--version', type=xsd_version_number, default='1.0', help="XSD schema validator to use (default is 1.0).") parser.add_argument('-L', dest='locations', nargs=2, type=str, action='append', metavar="URI/URL", help="schema location hint overrides.") parser.add_argument( '--generator', type=str, metavar='NAME', required=True, help="the generator to use. Option value can be one of " "{!r}.".format(tuple(GENERATORS_MAP))) parser.add_argument( '-o', '--output', type=str, default='.', metavar='DIRECTORY', help="where to write the rendered files, current dir by default.") parser.add_argument('-f', '--force', action="store_true", default=False, help="do not prompt before overwriting.") parser.add_argument('files', metavar='[TEMPLATE_FILE ...]', nargs='*', help="Jinja template files to be rendered.") args = parser.parse_args() loglevel = get_loglevel(args.verbosity) logger = logging.getLogger('xsdtools') logger.setLevel(loglevel) schema_class = XMLSchema if args.version == '1.0' else XMLSchema11 if args.schema is not None: schema = schema_class(args.schema, locations=args.locations, loglevel=loglevel) else: schema = None generator_class = get_generator_class(args.generator) base_path = pathlib.Path(args.output) if not base_path.exists(): base_path.mkdir() elif not base_path.is_dir(): raise XMLSchemaValueError("{!r} is not a directory".format( str(base_path))) template_files = {None: []} for path in map(pathlib.Path, args.files): if is_shell_wildcard(str(path)): template_files[None].append(str(path)) elif path.suffix not in ('.jinja', '.j2', '.jinja2'): pass elif path.is_file(): try: template_files[str(path.parent)].append(path.name) except KeyError: template_files[str(path.parent)] = [path.name] else: template_files[None].append(str(path)) rendered_templates = [] for searchpath, names in template_files.items(): generator = generator_class(schema, searchpath) rendered_templates.extend( generator.render_to_files(names, output_dir=args.output, force=args.force)) print("Rendered n.{} files ...".format(len(rendered_templates))) sys.exit(not rendered_templates)