Skip to content
This repository has been archived by the owner on Apr 29, 2023. It is now read-only.

Simple content with fixed value and attributes are not handled properly #110

Open
maciekwawro opened this issue Feb 13, 2019 · 2 comments
Open
Labels
Milestone

Comments

@maciekwawro
Copy link

I have something along the lines of schema.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/" xml:lang="en">
  <xsd:element name="Element" fixed="ElementValue">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string">
          <xsd:attribute name="attribute" type="xsd:string" use="required" fixed="AttributeValue"/>
        </xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

and the corresponding document.xml:

<?xml version="1.0" ?>
<example:Element xmlns:example="http://www.example.com/" attribute="AttributeValue">ElementValue</example:Element>

I could not find anything in specs that would forbid such declaration, and xmllint validates it fine:

$ xmllint --schema schema.xsd document.xml --noout
document.xml validates
$ xmllint --schema http://www.w3.org/2001/XMLSchema.xsd schema.xsd --noout
schema.xsd validates

However PyXB doesn't seem to handle that:

>>> import example
>>> xml = open('document.xml').read()
>>> data = example.CreateFromDocument(xml)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "example.py", line 65, in CreateFromDocument
    saxer.parse(io.BytesIO(xmld))
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 110, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "/usr/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 213, in feed
    self._parser.Parse(data, isFinal)
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 365, in end_element_ns
    self._cont_handler.endElementNS(pair, None)
  File "/usr/local/lib/python2.7/dist-packages/pyxb/binding/saxer.py", line 388, in endElementNS
    binding_object = this_state.endBindingElement()
  File "/usr/local/lib/python2.7/dist-packages/pyxb/binding/saxer.py", line 226, in endBindingElement
    self.__constructElement(self.__delayedConstructor, self.__attributes, args)
  File "/usr/local/lib/python2.7/dist-packages/pyxb/binding/saxer.py", line 116, in __constructElement
    self.__bindingInstance = new_object_factory(*content, **kw)
  File "/usr/local/lib/python2.7/dist-packages/pyxb/binding/basis.py", line 1631, in __call__
    args = [ self.compatibleValue(args[0], **kw) ]
  File "/usr/local/lib/python2.7/dist-packages/pyxb/binding/basis.py", line 1654, in compatibleValue
    raise pyxb.ElementChangeError(self, value)
pyxb.exceptions_.ElementChangeError: Value ElementValue for element {http://www.example.com/}Element incompatible with fixed content

Also see StackOverflow question.

@pabigot pabigot added the bug label Feb 13, 2019
@pabigot pabigot added this to the PyXB-1.2.7 milestone Feb 13, 2019
@pabigot
Copy link
Owner

pabigot commented Feb 13, 2019

Looks like _TypeBinding_mixin._CompatibleValue only handles the case where the element type is simple. With your schema it's a complex type with simple content, and it's returning an element of that type. In this case it should probably just return the content.

You can try patching your installation with something like this; I have no idea whether this change results in new bugs.

diff --git a/pyxb/binding/basis.py b/pyxb/binding/basis.py
index f624e0e6..1d433559 100644
--- a/pyxb/binding/basis.py
+++ b/pyxb/binding/basis.py
@@ -397,7 +397,10 @@ class _TypeBinding_mixin (utility.Locatable_mixin):
         # See if we have convert_string_values on, and have a string type that
         # somebody understands.
         if convert_string_values and value_type == six.text_type:
-            return cls(value)
+            rv = cls(value)
+            if isinstance(rv, complexTypeDefinition) and cls._IsSimpleTypeContent():
+                return rv.value()
+            return rv
 
         # Maybe this is a union?
         if issubclass(cls, STD_union):

@maciekwawro
Copy link
Author

Thanks. I don't know that either, but it certainly helps with this particular issue :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants