def check_json_serialization(self, root, converter=None, **kwargs): data1 = xmlschema.to_json(root, schema=self.schema, converter=converter, **kwargs) if isinstance(data1, tuple): data1 = data1[0] elem1 = xmlschema.from_json(data1, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem1, tuple): elem1 = elem1[0] data2 = xmlschema.to_json(elem1, schema=self.schema, converter=converter, **kwargs) if isinstance(data2, tuple): data2 = data2[0] if converter is ParkerConverter and any(XSI_TYPE in e.attrib for e in root.iter()): return # can't check encode equivalence if xsi:type is provided elif sys.version_info >= (3, 6): self.assertEqual(data2, data1, msg_tmpl % "serialized data changed at second pass") else: elem2 = xmlschema.from_json(data2, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem2, tuple): elem2 = elem2[0] try: self.assertIsNone(etree_elements_assert_equal(elem1, elem2, strict=False, skip_comments=True)) except AssertionError as err: self.assertIsNone(err, None)
def check_json_serialization(self, root, converter=None, **kwargs): lossy = converter in (ParkerConverter, AbderaConverter, ColumnarConverter) unordered = converter not in (AbderaConverter, JsonMLConverter) or \ kwargs.get('unordered', False) # Use str instead of float in order to preserve original data kwargs['decimal_type'] = str json_data1 = xmlschema.to_json(root, schema=self.schema, converter=converter, **kwargs) if isinstance(json_data1, tuple): json_data1 = json_data1[0] elem1 = xmlschema.from_json(json_data1, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem1, tuple): elem1 = elem1[0] if lax_encode: kwargs['validation'] = kwargs.get('validation', 'lax') json_data2 = xmlschema.to_json(elem1, schema=self.schema, converter=converter, **kwargs) if isinstance(json_data2, tuple): json_data2 = json_data2[0] if json_data2 != json_data1 and (lax_encode or lossy or unordered): # Can't ensure decode equivalence if the test case use defaults, # or the converter is lossy or the decoding is unordered. return if sys.version_info >= (3, 6): self.assertEqual(json_data2, json_data1, msg=xml_file) else: elem2 = xmlschema.from_json(json_data2, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem2, tuple): elem2 = elem2[0] try: self.assertIsNone(etree_elements_assert_equal( elem1, elem2, strict=False, skip_comments=True, unordered=unordered), msg=xml_file) except AssertionError as err: self.assertIsNone(err, msg=xml_file)
def check_json_serialization(self, root, converter=None, **kwargs): lossy = converter in (ParkerConverter, AbderaConverter, ColumnarConverter) unordered = converter not in (AbderaConverter, JsonMLConverter) or \ kwargs.get('unordered', False) data1 = xmlschema.to_json(root, schema=self.schema, converter=converter, **kwargs) if isinstance(data1, tuple): data1 = data1[0] elem1 = xmlschema.from_json(data1, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem1, tuple): elem1 = elem1[0] data2 = xmlschema.to_json(elem1, schema=self.schema, converter=converter, **kwargs) if isinstance(data2, tuple): data2 = data2[0] if data2 != data1 and (lax_encode or lossy or unordered): # Can't ensure decode equivalence if the test case use defaults, # or the converter is lossy or the decoding is unordered. return if sys.version_info >= (3, 6): if data1 != data2: print(data1) print(data2) print(converter, unordered) self.assertEqual( data2, data1, msg_tmpl % "serialized data changed at second pass") else: elem2 = xmlschema.from_json(data2, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem2, tuple): elem2 = elem2[0] try: self.assertIsNone( etree_elements_assert_equal(elem1, elem2, strict=False, skip_comments=True, unordered=unordered)) except AssertionError as err: self.assertIsNone(err, None)
def test_from_json_api(self): json_data = to_json(self.col_xml_file, lazy=True) with self.assertRaises(TypeError) as ctx: from_json(json_data, self.col_xsd_file) self.assertIn("invalid type <class 'str'> for argument 'schema'", str(ctx.exception)) col_schema = XMLSchema10(self.col_xsd_file) collection = from_json(json_data, schema=col_schema) self.assertEqual(collection.tag, '{http://example.com/ns/collection}collection') col_schema = XMLSchema10(self.col_xsd_file) collection = from_json(json_data, col_schema, json_options={'parse_float': Decimal}) self.assertEqual(collection.tag, '{http://example.com/ns/collection}collection')
def test_osp_system_structure_creation(): # create from a dict_xml obj = OspSystemStructure(xml_source=PATH_TO_TEST_SYSTEM_STRUCTURE) dict_xml = obj.to_dict_xml() xml_str = xmlschema.etree_tostring( xmlschema.from_json(json.dumps(dict_xml), obj.xs)) obj_ref = OspSystemStructure() obj_ref.from_xml(xml_str) dict_xml_ref = obj_ref.to_dict_xml() assertEqual(dict_xml, dict_xml_ref)
def test_json_dump_and_load(self): vh_xml_tree = ElementTree.parse(self.vh_xml_file) col_xml_tree = ElementTree.parse(self.col_xml_file) with open(self.vh_json_file, 'w') as f: xmlschema.to_json(self.vh_xml_file, f) with open(self.vh_json_file) as f: root = xmlschema.from_json(f, self.vh_schema) os.remove(self.vh_json_file) self.check_etree_elements(vh_xml_tree.getroot(), root) with open(self.col_json_file, 'w') as f: xmlschema.to_json(self.col_xml_file, f) with open(self.col_json_file) as f: root = xmlschema.from_json(f, self.col_schema) os.remove(self.col_json_file) self.check_etree_elements(col_xml_tree.getroot(), root)
def to_xml_str(self) -> str: """Convert the instance to XML string""" xs = xmlschema.XMLSchema(PATH_TO_XML_SCHEMA_FOR_LOGGING) json_text = json.dumps(self.to_dict_xml(), indent=2) et = xmlschema.from_json(json_text, xs) xml_str = xmlschema.etree_tostring(et) namespace = xmlschema.XMLResource(PATH_TO_XML_SCHEMA_FOR_LOGGING).get_namespaces()[''] xml_str = xml_str.replace('xmlns="%s"' % namespace, '') return xml_str
def from_json(self, source, validation='strict', **kwargs): """ Load JSON encoded data. Data is converted to an XML ElementTree structure and validated against the schema. :param source: a filepath to a JSON file or a string containing JSON data. :param validation: validation mode, can be 'strict', 'lax' or 'skip'. :param kwargs: other options to pass to the encoding method of the schema instance. :return: the root element of the XML ElementTree data structure and a list \ containing the detected errors. :raise: an :class:`xmlschema.XMLSchemaValidationError` if validation is strict \ and at least an error is found. """ if not isinstance(source, str): raise TypeError("the source argument must be a string!") preserve_root = kwargs.pop('preserve_root', True) try: json.loads(source) except ValueError: with open(source) as f: obj = xmlschema.from_json(f, self.schema, validation=validation, preserve_root=preserve_root) filename = source.strip() else: obj = xmlschema.from_json(source, self.schema, validation=validation, preserve_root=preserve_root) filename = None if isinstance(obj, tuple): self.root, self.errors = obj else: self.root, self.errors = obj, [] self.filename = filename self.format = 'json' if filename else None
def check_json_serialization(self, root, converter=None, **kwargs): data1 = xmlschema.to_json(root, schema=self.schema, converter=converter, **kwargs) if isinstance(data1, tuple): data1 = data1[0] elem1 = xmlschema.from_json(data1, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem1, tuple): elem1 = elem1[0] data2 = xmlschema.to_json(elem1, schema=self.schema, converter=converter, **kwargs) if isinstance(data2, tuple): data2 = data2[0] if sys.version_info >= (3, 6): self.assertEqual(data2, data1, msg_template % "serialized data changed at second pass") else: elem2 = xmlschema.from_json(data2, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem2, tuple): elem2 = elem2[0] try: self.assertIsNone(etree_elements_assert_equal(elem1, elem2, strict=False, skip_comments=True)) except AssertionError as err: self.assertIsNone(err, None)
def check_json_serialization(self, root, converter=None, **kwargs): lossy = converter in (ParkerConverter, AbderaConverter, ColumnarConverter) unordered = converter not in (AbderaConverter, JsonMLConverter) or \ kwargs.get('unordered', False) # Use str instead of float in order to preserve original data kwargs['decimal_type'] = str json_data1 = xmlschema.to_json(root, schema=self.schema, converter=converter, **kwargs) if isinstance(json_data1, tuple): json_data1 = json_data1[0] elem1 = xmlschema.from_json(json_data1, schema=self.schema, path=root.tag, converter=converter, **kwargs) if isinstance(elem1, tuple): elem1 = elem1[0] if lax_encode: kwargs['validation'] = kwargs.get('validation', 'lax') json_data2 = xmlschema.to_json(elem1, schema=self.schema, converter=converter, **kwargs) if isinstance(json_data2, tuple): json_data2 = json_data2[0] if json_data2 != json_data1 and (lax_encode or lossy or unordered): # Can't ensure decode equivalence if the test case use defaults, # white spaces are replaced/collapsed or the converter is lossy # or the decoding is unordered. return self.assertEqual(json_data2, json_data1, msg=xml_file)
def json2xml(): parser = argparse.ArgumentParser( prog=PROGRAM_NAME, add_help=True, description="encode a set of JSON files to XML.") 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( '-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='[JSON_FILE ...]', nargs='+', help="JSON files to be encoded to XML.") args = parser.parse_args() loglevel = get_loglevel(args.verbosity) schema_class = XMLSchema if args.version == '1.0' else XMLSchema11 converter = get_converter(args.converter) schema = schema_class(args.schema, locations=args.locations, loglevel=loglevel) 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 json_path in map(pathlib.Path, args.files): xml_path = base_path.joinpath(json_path.name).with_suffix('.xml') if xml_path.exists() and not args.force: print("skip {}: the destination file exists!".format( str(xml_path))) continue with open(str(json_path)) as fp: try: root, errors = from_json( source=fp, schema=schema, converter=converter, 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(json_path), str(xml_path))) else: tot_errors += len(errors) print("{} converted to {} with {} errors".format( str(json_path), str(xml_path), len(errors))) with open(str(xml_path), 'w') as fp: fp.write(etree_tostring(root)) sys.exit(tot_errors)
def to_xml_str(self): json_converted = json.dumps(self.to_dict_xml(), indent=2) return xmlschema.etree.etree_tostring( xmlschema.from_json(json_converted, self.xs))