Is it possible to use PyXB to generate a module from an XSD that has anonymous complex types that can have some basic type- and constraints-checking ?
Here's what I've managed so far:
Using a 3rd-Party (Anonymised) XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.foo.com" xmlns="http://www.foo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ResultSet">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="Bar">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="code" type="xs:string"/>
<xs:element minOccurs="0" name="description" type="xs:string"/>
<xs:element minOccurs="0" name="name" type="xs:string"/>
</xs:sequence>
<xs:attribute name="href" type="xs:string"/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I generated a python module:
> pyxbgen -u Foo.xsd -m Foo
Python for http://www.foo.com requires 1 modules
> ls
Foo.py Foo.xsd
Then in the python interpreter, I was able to create a ResultSet
instance and create entries under Bar
:
> python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyxb
>>> import Foo
>>> Foo
<module 'Foo' from 'Foo.py'>
>>> rs = Foo.ResultSet()
>>> rs
<Foo.CTD_ANON object at 0x7f7360834950>
>>> rs.Bar
<pyxb.binding.content._PluralBinding object at 0x7f7360834a90>
>>> rs.Bar.append( pyxb.BIND( name='a', code='b', description ='c' ) )
>>> rs.Bar
<pyxb.binding.content._PluralBinding object at 0x7f39f1018a90>
>>> [x for x in rs.Bar ]
[<Foo.CTD_ANON_ object at 0x7f39f1018b90>]
And I'm able to interact with the members of rs.Bar[0]
.
BUT what bothers me is that I can also:
>>> rs.Bar.append( pyxb.BIND( name='a' ) )
and it'll accept it, even though the code
element in the anonymous complexType
has an attribute of minOccurs="1"
. I gather from reading the docs and some other questions on StackOverflow that PyXB is trying to reverse-engineer the data types on the fly, so that might explain the permissiveness.
I'd like if possible to overlay something on the whole process that allows me to basically say:
>>> rs.Bar.append( Something( name='a', code='b' ) )
and have it complain about any missing parameters. So far I have mulled over just writing my own functions that return the result of pyxb.BIND()
with the appropriate parameters, but this implies quite a degree of manual intervention.
Is there a way with PyXB to create such smarts automatically ?