首页 > 解决方案 > spyne 生成无效架构

问题描述

我正在尝试使用 master 分支中的 spyne,因为已发布的版本与 python3 不兼容,并且我定义了如下模型:

class currency(ComplexModel):                                                   
    data = XmlData(Decimal)                                                     


class mntCurrency(currency):                                                    
    code = XmlAttribute(String)                                                 


class CreditLmt(ComplexModel):                                                  
    curr = mntCurrency

我已将这些模型插入到一个简单的 HelloWorld 服务中,该服务返回 CreditLmt 作为响应。但是当我尝试运行我的肥皂服务器时,spyne 会抱怨以下内容:

lxml.etree.XMLSchemaParseError:元素'{ http://www.w3.org/2001/XMLSchema }extension':内容无效。预期为 (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))).,第 16 行

这是正确的,因为 spyne 生成以下 xsd:

 <xs:complexType name="mntCurrency">                                           
    <xs:complexContent>                                                         
      <xs:extension base="tns:currency">                                        
        <xs:simpleContent>                                                      
          <xs:extension base="xs:decimal">                                      
            <xs:attribute name="code" type="xs:string"/>                        
          </xs:extension>                                                       
        </xs:simpleContent>                                                     
        <xs:sequence>                                                           
          <xs:element name="test" type="xs:token" minOccurs="0" nillable="true"/>
        </xs:sequence>                                                          
      </xs:extension>                                                           
    </xs:complexContent>                                                        
  </xs:complexType>

我使用 XmlData 是因为我希望得到这样的响应:

<tns:currency code="826">10.0</tns:currency>

那么如何定义我的模型呢?

标签: lxmlspyne

解决方案


生成此元素的示例:

<tns:currency code="826">10.0</tns:currency>

...如下:

from spyne import *
from spyne.util.xml import get_object_as_xml

from lxml import etree


class Currency(ComplexModel):
    value = XmlData(Decimal)
    code = XmlAttribute(Integer32(values=[826, 234, 555]))


class SomeObject(ComplexModel):
    handle = Unicode
    currency = Currency


obj = SomeObject(handle="aaaa", currency=Currency(value=D('123.45'), code=555))
elt = get_object_as_xml(obj)
print(etree.tostring(elt, pretty_print=True))

至于错误,它直接来自libxml。这本质上是说 Xml Schema 标准不允许XmlDataComplexModel 子类中的单独条目。如果您认为这是一个错误,您必须向 Xml Schema 工作组投诉。


推荐阅读