No, PyXB is actually correct here, as demonstrated by independent validation:
llc[106]$ xmllint --schema x.xsd xa.xml
<?xml version="1.0"?><ns1:ArrayOfAxmlns:ns1="mynf"><ns1:A/></ns1:ArrayOfA>
xa.xml validates
llc[107]$ xmllint --schema x.xsd xb.xml
<?xml version="1.0"?><ns1:ArrayOfAxmlns:ns1="mynf"><ns1:B/></ns1:ArrayOfA>
xb.xml:1: element B: Schemas validity error : Element '{mynf}B': This element is not expected. Expected is ( {mynf}A ).
xb.xml fails to validate
In short, your schema does not allow an element {mynf}B to occur within complex type {mynf}ArrayOfAType. PyXB is being helpful here, and implicitly converting the (empty) content of the instance you pass into an instance A which is permitted.
There are two underlying issues. First, you have two distinct elements A: a global {mynf}A and a local A with no namespace{mynf}A that is scoped only within {mynf}ArrayOfAType. This actually is perfectly valid, but is probably not what you intend.
The second is that XML is not like object-oriented languages where B extends A means B isa A. You need to use substitution groups to accomplish what you want. Here's a schema that works:
<?xml version="1.0" encoding="utf-8"?><xs:schematargetNamespace="mynf"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:tns="mynf"elementFormDefault="qualified"><xs:complexTypename="ArrayOfAType"><xs:sequence><!-- Change this to be a reference to {mynf}A --><xs:elementref="tns:A"minOccurs="0"maxOccurs="unbounded"/></xs:sequence></xs:complexType><xs:elementname="ArrayOfA"nillable="true"type="tns:ArrayOfAType"/><xs:complexTypename="AType"/><xs:elementname="A"nillable="true"type="tns:AType"/><xs:complexTypename="BType"><xs:complexContentmixed="false"><xs:extensionbase="tns:AType"/></xs:complexContent></xs:complexType><!-- Add this to the substitution group for {mynf}A --><xs:elementname="B"nillable="true"type="tns:BType"substitutionGroup="tns:A"/></xs:schema>
Then your test program produces the desired output (and both sample documents validate).
Last edit: Peter A. Bigot 2014-10-16
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
When I run
the output is
<ns1:B xmlns:ns1="mynf"/> <ns1:ArrayOfA xmlns:ns1="mynf"><ns1:A/></ns1:ArrayOfA>I would expect the array to be:
<?xml version="1.0" ?><ns1:ArrayOfA xmlns:ns1="mynf"><ns1:B/></ns1:ArrayOfA>
Is this a bug, or am I missing something?
test.py is
test.xsd
No, PyXB is actually correct here, as demonstrated by independent validation:
In short, your schema does not allow an element
{mynf}B
to occur within complex type{mynf}ArrayOfAType
. PyXB is being helpful here, and implicitly converting the (empty) content of the instance you pass into an instanceA
which is permitted.There are two underlying issues. First, you have two distinct elements
A
: a global{mynf}A
and a localA
with no namespace{mynf}A
that is scoped only within{mynf}ArrayOfAType
. This actually is perfectly valid, but is probably not what you intend.The second is that XML is not like object-oriented languages where
B
extendsA
meansB
isaA
. You need to use substitution groups to accomplish what you want. Here's a schema that works:Then your test program produces the desired output (and both sample documents validate).
Last edit: Peter A. Bigot 2014-10-16