Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
)
)
schema.set_ns_prefix("tns", "http://tests.python-zeep.org/")
xml = load_xml(
b"""
BAD VALUE
"""
)
elm = schema.get_element("{http://tests.python-zeep.org/}container")
with pytest.raises(exceptions.XMLParseError) as exc:
result = elm.parse(xml, schema)
assert "BAD_ELEMENT" in str(exc)
xml = load_xml(
b"""
value2
"""
)
result = elm.parse(xml, schema)
assert result.el2 == "value2"
def as_qname(value, nsmap, target_namespace=None):
"""Convert the given value to a QName"""
value = value.strip() # some xsd's contain leading/trailing spaces
if ":" in value:
prefix, local = value.split(":")
# The xml: prefix is always bound to the XML namespace, see
# https://www.w3.org/TR/xml-names/
if prefix == "xml":
namespace = "http://www.w3.org/XML/1998/namespace"
else:
namespace = nsmap.get(prefix)
if not namespace:
raise XMLParseError("No namespace defined for %r (%r)" % (prefix, value))
# Workaround for https://github.com/mvantellingen/python-zeep/issues/349
if not local:
return etree.QName(XSD, "anyType")
return etree.QName(namespace, local)
if target_namespace:
return etree.QName(target_namespace, value)
if nsmap.get(None):
return etree.QName(nsmap[None], value)
return etree.QName(value)
return
# Parse elements. These are always indicator elements (all, choice,
# group, sequence)
for name, element in self.elements_nested:
try:
result = element.parse_xmlelements(
elements, schema, name, context=context)
if result:
init_kwargs.update(result)
except UnexpectedElementError as exc:
raise XMLParseError(exc.message)
# Check if all children are consumed (parsed)
if elements:
raise XMLParseError("Unexpected element %r" % elements[0].tag)
# Parse attributes
if attributes:
attributes = copy.copy(attributes)
for name, attribute in self.attributes:
if attribute.name:
if attribute.qname.text in attributes:
value = attributes.pop(attribute.qname.text)
init_kwargs[name] = attribute.parse(value)
else:
init_kwargs[name] = attribute.parse(attributes)
return self(**init_kwargs)
return
# Load the XML
schema_node = load_external(
location,
transport=self.schema._transport,
base_url=self.document._location,
settings=self.schema.settings,
)
# Check if the xsd:import namespace matches the targetNamespace. If
# the xsd:import statement didn't specify a namespace then make sure
# that the targetNamespace wasn't declared by another schema yet.
schema_tns = schema_node.get("targetNamespace")
if namespace and schema_tns and namespace != schema_tns:
raise XMLParseError(
(
"The namespace defined on the xsd:import doesn't match the "
"imported targetNamespace located at %r "
)
% (location),
filename=self.document._location,
sourceline=node.sourceline,
)
# If the imported schema doesn't define a target namespace and the
# node doesn't specify it either then inherit the existing target
# namespace.
elif not schema_tns and not namespace:
namespace = self.document._target_namespace
schema = self.schema.create_new_document(
# group, sequence)
assert len(self.elements_nested) < 2
for name, element in self.elements_nested:
try:
result = element.parse_xmlelements(
elements, schema, name, context=context
)
if result:
init_kwargs.update(result)
except UnexpectedElementError as exc:
raise XMLParseError(exc.message)
# Check if all children are consumed (parsed)
if elements:
if schema.settings.strict:
raise XMLParseError("Unexpected element %r" % elements[0].tag)
else:
init_kwargs["_raw_elements"] = elements
# Parse attributes
if attributes:
attributes = copy.copy(attributes)
for name, attribute in self.attributes:
if attribute.name:
if attribute.qname.text in attributes:
value = attributes.pop(attribute.qname.text)
init_kwargs[name] = attribute.parse(value)
else:
init_kwargs[name] = attribute.parse(attributes)
value = self._value_class(**init_kwargs)
schema_type = schema_type or self
def _create_error(self, message, node):
return XMLParseError(
message, filename=self.document._location, sourceline=node.sourceline
)
:param node: The XML node
:type node: lxml.etree._Element
:param parent: The parent XML node
:type parent: lxml.etree._Element
"""
schema_node = None
namespace = node.get("namespace")
location = node.get("schemaLocation")
if location:
location = normalize_location(
self.schema.settings, location, self.document._base_url
)
if not namespace and not self.document._target_namespace:
raise XMLParseError(
"The attribute 'namespace' must be existent if the "
"importing schema has no target namespace.",
filename=self._document.location,
sourceline=node.sourceline,
)
# We found an empty statement, this needs to trigger 4.1.2
# from https://www.w3.org/TR/2012/REC-xmlschema11-1-20120405/#src-resolve
# for QName resolving.
# In essence this means we will resolve QNames without a namespace to no
# namespace instead of the target namespace.
# The following code snippet works because imports have to occur before we
# visit elements.
if not namespace and not location:
self.document._has_empty_import = True