使用 xsd 文件时如何避免在 pyxb 中创建匿名 类
How to avoid the creation of anonymous classes in pyxb when using xsd file
我正在尝试实现与某些 API 的连接。在通信过程中,我得到了 payload xml 代码。他们提供了带有 xml 描述的 .xsd-file。现在我想解析 xml 字符串并在 return 中获取适当的 class。这个功能似乎最好由 PyXB 实现。
为了创建 python 绑定,我使用了以下代码:
pyxben -u my_schema.csd -m my_schema
如果我在 python3 中导入 my_schema 并使用 my_schema.CreateFromDocument('some correct looking xml'),对于某些 classes 它 returns正确的 class,对于某些 class 来说,它 return 是一些匿名的 class 类型。变量都正确实现了,这意味着它们成为 returned class 的属性,但是 class 的类型不正确。
这从源码my_schema.py中可以明显看出,因为class的类型设置为CTD_ANON_XX。一些朋友在 C# 中实现了相同的东西并且一切正常,所以 xsd 方案似乎没问题(并且消息来源表明它应该没问题)。
python 绑定有效,例如对于以下 class:
<xs:complexType name="OrdrBookEntry">
<xs:attribute name="ordrId" type="longType" use="required"/>
<xs:attribute name="qty" type="quantityType" use="required"/>
<xs:attribute name="px" type="priceType" use="required"/>
<xs:attribute name="ordrEntryTime" type="dateTimeType" use="required"/>
<xs:attribute name="ordrExeRestriction" type="ordrRestrictionType" use="optional"/>
<xs:attribute name="ordrType" type="ordrType" use="optional" />
</xs:complexType>
但是对于以下类型它失败了:
<xs:element name="PblcOrdrBooksResp" final="#all">
<xs:complexType>
<xs:annotation>
<xs:documentation>
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="StandardHeader" type="standardHeaderType" minOccurs="1" maxOccurs="1"/>
<xs:element name="OrdrbookList" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="OrdrBook" type="OrdrBook" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
如前所述,该定义在 C# 中运行良好。这是 pyxb 中的错误还是 xml 定义有问题?我是否想念 pyxb 的用法?谁能帮我?
我想避免玩弄方案定义。如果有新版本,我将需要开始一遍又一遍地修复所有内容...
编辑:
澄清一下:我们得到一个 xml header 如下所示:
<?xml version="1.0" ?><PblcOrdrBooksResp xmlns="www.apisite.com">
<StandardHeader marketId="EPEX"/>
<OrdrbookList>
...
</OrdrbookList></PblcOrdrBooksResp>
我们现在想用pyxb发起正确的class然后从object中读取发送了什么样的内容!?
所以从上面的例子我们会期望(或希望)
my_object = mypyxb.module.CreatefromDocument(xml)
type(my_object)
到return其类型
PblcOrdrBooksResp
或者至少有一个类型正确的属性...
这既不是 PyXB 中的错误,也不是您的架构有问题——这是架构设计的结果。内部 OrdrBookList
元素的类型本身没有名称,因为它是在另一种类型的上下文中定义的,即封闭元素 PblkOrdrBooksResp
的类型(也没有姓名)。元素和类型不是一回事,因此它们必须具有 different names:当同一元素在不同上下文中使用不同类型时,尝试为内部类型推断非匿名名称可能会产生冲突。 PyXB 通过明确匿名来避免这种情况。
the PyXB documentation. See also this posting 和该论坛上的其他人讨论了这种架构样式以及如何处理它。
回复编辑
您正在从 xml 实例化 class。您将 XML 转换为 Python 类型的 Python 实例,该实例对应于没有名称的 XML 类型。 Python 类型有一个名称:一个唯一标识符,表明它是一个匿名复杂类型。
听起来你所说的 "class" 就是 PyXB 所说的 element。 PyXB 允许您在代码中使用元素,就好像它们是 classes 一样来创建绑定实例,但它们不是 classes。
您从 XML 创建的实例绑定到具有 expanded name. You'll see it when you convert the instance back to XML, or can get the name, scope, and other information by calling my_object._element():
的元素
print my_object._element().name()
我正在尝试实现与某些 API 的连接。在通信过程中,我得到了 payload xml 代码。他们提供了带有 xml 描述的 .xsd-file。现在我想解析 xml 字符串并在 return 中获取适当的 class。这个功能似乎最好由 PyXB 实现。
为了创建 python 绑定,我使用了以下代码:
pyxben -u my_schema.csd -m my_schema
如果我在 python3 中导入 my_schema 并使用 my_schema.CreateFromDocument('some correct looking xml'),对于某些 classes 它 returns正确的 class,对于某些 class 来说,它 return 是一些匿名的 class 类型。变量都正确实现了,这意味着它们成为 returned class 的属性,但是 class 的类型不正确。
这从源码my_schema.py中可以明显看出,因为class的类型设置为CTD_ANON_XX。一些朋友在 C# 中实现了相同的东西并且一切正常,所以 xsd 方案似乎没问题(并且消息来源表明它应该没问题)。
python 绑定有效,例如对于以下 class:
<xs:complexType name="OrdrBookEntry">
<xs:attribute name="ordrId" type="longType" use="required"/>
<xs:attribute name="qty" type="quantityType" use="required"/>
<xs:attribute name="px" type="priceType" use="required"/>
<xs:attribute name="ordrEntryTime" type="dateTimeType" use="required"/>
<xs:attribute name="ordrExeRestriction" type="ordrRestrictionType" use="optional"/>
<xs:attribute name="ordrType" type="ordrType" use="optional" />
</xs:complexType>
但是对于以下类型它失败了:
<xs:element name="PblcOrdrBooksResp" final="#all">
<xs:complexType>
<xs:annotation>
<xs:documentation>
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="StandardHeader" type="standardHeaderType" minOccurs="1" maxOccurs="1"/>
<xs:element name="OrdrbookList" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="OrdrBook" type="OrdrBook" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
如前所述,该定义在 C# 中运行良好。这是 pyxb 中的错误还是 xml 定义有问题?我是否想念 pyxb 的用法?谁能帮我?
我想避免玩弄方案定义。如果有新版本,我将需要开始一遍又一遍地修复所有内容...
编辑: 澄清一下:我们得到一个 xml header 如下所示:
<?xml version="1.0" ?><PblcOrdrBooksResp xmlns="www.apisite.com">
<StandardHeader marketId="EPEX"/>
<OrdrbookList>
...
</OrdrbookList></PblcOrdrBooksResp>
我们现在想用pyxb发起正确的class然后从object中读取发送了什么样的内容!?
所以从上面的例子我们会期望(或希望)
my_object = mypyxb.module.CreatefromDocument(xml)
type(my_object)
到return其类型
PblcOrdrBooksResp
或者至少有一个类型正确的属性...
这既不是 PyXB 中的错误,也不是您的架构有问题——这是架构设计的结果。内部 OrdrBookList
元素的类型本身没有名称,因为它是在另一种类型的上下文中定义的,即封闭元素 PblkOrdrBooksResp
的类型(也没有姓名)。元素和类型不是一回事,因此它们必须具有 different names:当同一元素在不同上下文中使用不同类型时,尝试为内部类型推断非匿名名称可能会产生冲突。 PyXB 通过明确匿名来避免这种情况。
the PyXB documentation. See also this posting 和该论坛上的其他人讨论了这种架构样式以及如何处理它。
回复编辑
您正在从 xml 实例化 class。您将 XML 转换为 Python 类型的 Python 实例,该实例对应于没有名称的 XML 类型。 Python 类型有一个名称:一个唯一标识符,表明它是一个匿名复杂类型。
听起来你所说的 "class" 就是 PyXB 所说的 element。 PyXB 允许您在代码中使用元素,就好像它们是 classes 一样来创建绑定实例,但它们不是 classes。
您从 XML 创建的实例绑定到具有 expanded name. You'll see it when you convert the instance back to XML, or can get the name, scope, and other information by calling my_object._element():
的元素print my_object._element().name()