使用PYXB解析XML。无法获取嵌套的匿名元素
我使用PYXB(pyxbgen)为以下的xsd文件创建了Python绑定,使用的命令如下:
pyxbgen -u Event.xsd -m Event
pyxbgen -u Shape.xsd -m Shape
pyxbgen -u flow-tags.xsd -m flow-tags
通过生成的绑定,我可以访问所有的“事件”数据,但我不知道怎么访问“细节”元素和数据。具体来说,就是形状元素中的椭圆和多边形(带有顶点数据)。细节元素是一个匿名类型。
这是我目前写的代码:
import Shape, Event, flow-tags
xml = '''
<event how="h-p" opex="e-TEST" qos="7-r-g" stale="2014-04-21T20:50:01.85Z" start="2014-04-21T20:48:01.85Z" time="2014-04-21T20:48:01.85Z" type="a-n-A-M-F-R-Z" uid="6716" version="2.0"><detail><_flow-tags_ debug="2014-04-21T20:48:01.00Z" /><shape><ellipse angle="33" major="44" minor="22" /><polyline closed="1"><vertex hae="1" lat="44" lon="-77" /></polyline></shape></detail><point ce="122.8" hae="817.2" lat="42.5612194" le="431.3" lon="-71.302077" /></event>
'''
event = Event.CreateFromDocument(xml)
print event.uid
print event.point.lon
detail = event.detail
#not sure what goes after this to get content of detail data?????
以下是我使用的Event.xsd和Shape.xsd文件。它们不是我的,所以如果文件有问题,我无法进行修改。
Event.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="event">
<xs:annotation>
<xs:documentation>Event Definition</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element ref="point" />
<xs:element ref="detail" minOccurs="0" />
</xs:all>
<xs:attribute name="version" use="required">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:minInclusive value="2" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="type" use="required">
<xs:annotation>
<xs:documentation>
The "type" attribute
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\w+(-\w+)*(;[^;]*)?" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="access" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
The access field
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="qos" use="optional">
<xs:annotation>
<xs:documentation>
format - digit-character-character
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\d-\w-\w" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="opex" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>
The opex field
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="uid" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
The "uid" attribute
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="time" type="xs:dateTime" use="required">
<xs:annotation>
<xs:documentation>
The XML schema includes three time values:
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="start" type="xs:dateTime" use="required">
<xs:annotation>
<xs:documentation>
format - DTG
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="stale" type="xs:dateTime" use="required">
<xs:annotation>
<xs:documentation>
The "stale" attribute
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="how" use="required">
<xs:annotation>
<xs:documentation>
format = character-character
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\w(-\w+)*" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="detail">
<xs:annotation>
<xs:documentation>
format
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute processContents="skip" />
</xs:complexType>
</xs:element>
<xs:element name="point">
<xs:complexType>
<xs:attribute name="lat" use="required">
<xs:annotation>
<xs:documentation>Latitude based on WGS-84 ellipsoid in signed
degree-decimal format (e.g. -33.350000). Range -90 -> +90.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:minInclusive value="-90" />
<xs:maxInclusive value="90" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="lon" use="required">
<xs:annotation>
<xs:documentation>Longitude based on WGS-84 ellipsoid in signed
degree-decimal format (e.g. 44.383333). Range -180 -> +180.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:minInclusive value="-180" />
<xs:maxInclusive value="180" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="hae" type="xs:decimal" use="required">
<xs:annotation>
<xs:documentation>HAE acronym for Height above Ellipsoid based on
WGS-84 ellipsoid (measured in meters).
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ce" type="xs:decimal" use="required">
<xs:annotation>
<xs:documentation>
Circular Error
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="le" type="xs:decimal" use="required">
<xs:annotation>
<xs:documentation>
Linear Error
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
Shape.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema http://www.w3.org/2001/XMLSchema.xsd"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:simpleType name="nonNegativeDecimal">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0" />
</xs:restriction>
<!-- Defined as global type for XML Gallery manifest reference than
any other reason -->
</xs:simpleType>
<xs:element name="shape">
<xs:annotation>
<xs:documentation></xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="ellipse" minOccurs="0">
<xs:annotation>
<xs:documentation>The "ellipse" is a common shape abstraction used
by many geomanipulation applications; it is supported natively.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="major" type="nonNegativeDecimal"
use="required">
<xs:annotation>
<xs:documentation>Ellipse major axis (meters)</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="minor" type="nonNegativeDecimal"
use="required">
<xs:annotation>
<xs:documentation>Ellipse minor axis (meters)</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="angle" type="xs:decimal" use="required">
<xs:annotation>
<xs:documentation>Orientation of major axis with respect to true
north.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="level" type="xs:integer" use="optional">
<xs:annotation>
<xs:documentation>"level"
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="extrude" type="xs:nonNegativeInteger"
use="optional">
<xs:annotation>
<xs:documentation>A "Height" of the ellipse used to make the
flat object encompas a volume.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="polyline" minOccurs="0">
<xs:annotation>
<xs:documentation>The poly line provides a mechanism to express
arbitrarily complex two-dimenstional shapes.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="vertex" minOccurs="2" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="lat" use="required">
<xs:annotation>
<xs:documentation>Latitude based on WGS-84 ellipsoid in
signed degree-decimal format (e.g. -33.350000). Range -90 ->
+90. Positive values denote north.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:minInclusive value="-90" />
<xs:maxInclusive value="90" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="lon" use="required">
<xs:annotation>
<xs:documentation>Longitude based on WGS-84 ellipsoid in
signed degree-decimal format (e.g. 44.383333). Range -180 ->
+180. Positive values denote east.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:minInclusive value="-180" />
<xs:maxInclusive value="180" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="hae" type="xs:decimal" use="optional">
<xs:annotation>
<xs:documentation>Height Above Ellipsoid (HAE) in Meters.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="level" type="xs:integer">
<xs:annotation>
<xs:documentation>"level"
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="closed" type="xs:boolean"
default="true">
<xs:annotation>
<xs:documentation>True if the list of verticies should be
considered a closed polygon (an implicit line will be added
from vertex N to vertex 0).
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="dxf" minOccurs="0">
<xs:annotation>
<xs:documentation>This is a hook for an arbitrary 3D DXF
description of a volume of space.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="level" type="xs:integer">
<xs:annotation>
<xs:documentation>"level" </xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="version" type="xs:decimal" use="optional">
<xs:annotation>
<xs:documentation>Version tag for this sub schema. Can be used to
ensure upward compatibility with future revisions.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
flow-tags.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema http://www.w3.org/2001/XMLSchema.xsd"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="_flow-tags_">
<xs:annotation>
<xs:documentation>This is a detail sub-schema</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:decimal" use="optional" />
<xs:anyAttribute processContents="lax">
<xs:annotation>
<xs:documentation>A system-specific flowtag identifier.
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
</xs:element>
非常感谢任何帮助!
1 个回答
2
在details元素中,如果有一些子元素不被识别,它们会被当作通配符添加,可以这样访问:
detail = event.detail
for elt in detail.wildcardElements():
print elt
不过,这些元素都是DOM实例(一个是_flow-tags_,一个是shape)。通常情况下,PyXB会把已经加载到应用程序中的元素转换为绑定,但它们仍然会存储在wildcardElements()数组中。这里没有发生这种情况,因为你使用的两个模式都没有命名空间,但被当作独立的模式来处理。在这两个模式中都没有元素_flow-tags_,而shape没有被转换为绑定,因为来自Shape模式的元素在Event使用的缺失命名空间中无法被识别。
由于我不知道这些模式是从哪里来的,所以我不能确定它们应该如何使用,但一种方法是把它们合并成一个父模式,如下所示:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="Shape.xsd"/>
<xs:include schemaLocation="Event.xsd"/>
</xs:schema>
然后从这个模式构建绑定:
pyxbgen -u combine.xsd -m combine
接着你可以这样导入这些绑定,它们包含了Event和Shape组件:
import pyxb
import combine
xml = '''
<event how="h-p" opex="e-TEST" qos="7-r-g" stale="2014-04-21T20:50:01.85Z" start="2014-04-21T20:48:01.85Z" time="2014-04-21T20:48:01.85Z" type="a-n-A-M-F-R-Z" uid="6716" version="2.0"><detail><_flow-tags_ debug="2014-04-21T20:48:01.00Z" /><shape><ellipse angle="33" major="44" minor="22" /><polyline closed="1"><vertex hae="1" lat="44" lon="-77" /></polyline></shape></detail><point ce="122.8" hae="817.2" lat="42.5612194" le="431.3" lon="-71.302077" /></event>
'''
try:
event = combine.CreateFromDocument(xml)
except pyxb.IncompleteElementContentError as ex:
print ex.details()
你会发现这个示例文档是无效的,原因是出现了以下错误:
The containing element polyline is defined at Shape.xsd[65:12].
The containing element type <class 'combine.CTD_ANON_2'> is defined at Shape.xsd[71:16]
The <class 'combine.CTD_ANON_2'> automaton is not in an accepting state.
Any accepted content has been stored in instance
The following element and wildcard content would be accepted:
An element vertex per Shape.xsd[73:24]
No content remains unconsumed
如果你查看Shape.xsd的第73行,你会看到一个多边形线需要至少两个顶点元素。如果你把文档修正为有第二个顶点,那么details.wildcardElements()的第一个成员仍然是一个DOM元素实例,但第二个将是一个shape绑定。