Reputation: 96264
I followed the instructions from this thread, and from this XML:
<?xml version="1.0" encoding="UTF-8" ?>
<my_report>
<something>
<foo>
Yes
</foo>
</something>
<something_else>
<id>4</id>
<foo>Finally</foo>
<score>0.2</score>
</something_else>
</my_report>
I created the following XSD schema using this tool online.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="my_report">
<xs:complexType>
<xs:sequence>
<xs:element name="something">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="foo"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="something_else">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:byte" name="id"/>
<xs:element type="xs:string" name="foo"/>
<xs:element type="xs:float" name="score"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I then called pyxben -u my_schema.csd -m my_schema
in the shell, and then tried to use the bindings build objects:
from my_schema import my_report
my_xml_report = my_report()
This seems to work so far (I can access my_xml_report.something
). However, when I try to fill in a nested element:
my_xml_report.something.foo = "No"
I get the error 'NoneType'object has no atttribute 'foo'
.
The documentation talks about anonymous types
which seem to be related to my problem, but I still can't get it to work:
import pyxb
my_xml_report.something = pyxb.BIND('foo', "No")
I get the error MixedContentError: invalid non-element content
How can I fill in this XML?
Upvotes: 1
Views: 3328
Reputation: 989
Denormalized schema are difficult, and you may need to try several approaches to provide the information required. Here's an annotated example, though I'm using PyXB 1.2.3 so the capabilities might be a little more complete:
import pyxb
import my_schema
rep = my_schema.my_report()
# The something element here is very simple, with a single string
# element. For the inner string element foo PyXB can figure things
# out for itself. For the outer element it needs help.
#
# In a normalized schema where the type of something was tSomething,
# you would do:
#
# rep.something = tSomething('yes')
#
# Without a tSomething easily reachable, to build it up piece-by-piece
# you could do:
rep.something = pyxb.BIND() # Create an instance of whatever type satisfies something
rep.something.foo = 'yes' # Assign to the foo element of what got created
# You can then optimize. Here pyxb.BIND substitutes for the something
# element wrapper around that string, and figures out for itself that
# the "yes" can only go in the foo element:
rep.something = pyxb.BIND('yes')
# In fact, sometimes PyXB can even figure out the intermediate
# intermediate layers:
rep.something = 'yes'
# No more than two of them, though (and the lowest must be a simple type).
# Similarly here pyxb.BIND substitutes for the type of the
# something_else element. Again the inner content is unambiguous and
# sequential, so the values can be provided in the constructor.
rep.something_else = pyxb.BIND(4, 'finally', 0.2)
print rep.toxml('utf-8')
Upvotes: 5