使用PYXB解析XML。无法获得嵌套的匿名元素

时间:2014-04-21 21:28:08

标签: python xml xsd pyxb

我使用命令在以下xsd文件上使用PYXB(pyxbgen)创建了Python绑定:

pyxbgen -u Event.xsd -m Event
pyxbgen -u Shape.xsd -m Shape
pyxbgen -u flow-tags.xsd -m flow-tags

使用生成的绑定,我可以访问所有"事件"数据,但我无法看到如何访问"详细信息"元素和数据。具体来说,形状元素的椭圆和多边形(带顶点数据)。 detail元素是匿名类型。 这是我到目前为止的代码:

    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>

流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 个答案:

答案 0 :(得分:2)

无法识别的详细信息子元素将添加为通配符,并且可以通过以下方式访问:

detail = event.detail
for elt in detail.wildcardElements():
    print elt

但是,这些元素都是DOM实例(一个用于_flow-tags_,一个用于形状)。通常,PyXB将转换已加载到应用程序中的任何绑定的元素,尽管它们仍将存储在wildcardElements()数组中。这不会发生在这里,因为您使用的两个模式都缺少名称空间,但正在被翻译为独立模式。在任一模式中都没有元素_flow-tags_,但是形状没有被转换为绑定,因为在用于Event的缺席命名空间内无法识别Shape模式中的元素。

不知道这些模式的来源我不知道它们应该如何使用,但一种方法是将它们组合成父模式,如下所示:

<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元素实例,但第二个将是形状绑定。