是否可以使用PyXB从具有匿名复杂类型的XSD生成模块,这些类型可以进行一些基本的类型和约束检查?
以下是我迄今为止所做的工作:
使用第三方(匿名) 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>我生成了一个python模块:
> pyxbgen -u Foo.xsd -m Foo
Python for http://www.foo.com requires 1 modules
> ls
Foo.py Foo.xsd然后,在python解释器中,我能够创建一个ResultSet实例并在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>]我可以和rs.Bar[0]的成员互动。
但困扰我的是我也可以:
>>> rs.Bar.append( pyxb.BIND( name='a' ) )即使匿名code中的complexType有一个属性minOccurs="1",它也会接受它。通过阅读StackOverflow上的文档和其他一些问题,我了解到PyXB正在试图反向设计数据类型,因此这可能解释了这种随意性。
如果可能的话,我想在整个过程中覆盖一些内容,这样我基本上可以说:
>>> rs.Bar.append( Something( name='a', code='b' ) )让它抱怨缺少的参数。到目前为止,我已经考虑过编写自己的函数,这些函数用适当的参数返回pyxb.BIND()的结果,但这意味着一定程度的手动干预。
有PyXB自动创建这种智能的方法吗?
发布于 2014-07-08 11:12:37
PyXB并不是因为逆向工程而允许使用,而是因为它在构造元素时不验证元素,在分配给元素时也不验证复杂类型。这是因为它可能需要多个Python语句来为元素分配必要的内容:它并不总是通过参数合理地提供给pyxb.BIND()。
例如,可以通过执行以下操作来完成代码:
rs.Bar.append( pyxb.BIND( name='a' ) )
rs.Bar[-1].code = '42'此时,rs将有效。
如果希望在对象被追加时执行验证,则应该使用一个中间函数来验证所追加的元素。以下说明如何在传入参数可能是未解析的pyxb.BIND结构的情况下执行此操作:
import pyxb
import Foo
def checkedAppendBar(rs, bar):
rs.Bar.append(bar)
bar = rs.Bar[-1]
try:
bar.validateBinding()
except pyxb.ValidationError as e:
print e.details()
return bar
rs = Foo.ResultSet()
# Fails:
#bar = checkedAppendBar(rs, pyxb.BIND(name='a'))
bar = checkedAppendBar(rs, pyxb.BIND(name='a', code='42'))https://stackoverflow.com/questions/24361135
复制相似问题