1

我正在尝试使用 PyXB 解析自定义 XML 文件格式。因此,我首先编写了以下 XML 模式:

<?xml version="1.0"?>                                                           
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">                         
    <xs:element name="outertag" minOccurs="0" maxOccurs="1">                    
        <xs:complexType>                                                        
            <xs:all>                                                            
                <xs:element name="innertag0"                                    
                            minOccurs="0"                                       
                            maxOccurs="unbounded"/>                             
                <xs:element name="innertag1"                                    
                            minOccurs="0"                                       
                            maxOccurs="unbounded"/>                             
            </xs:all>                                                           
        </xs:complexType>                                                       
    </xs:element>                                                               
</xs:schema>

我使用以下 pyxbgen 命令生成 Python 模块的源代码 py_schema_module.py:

pyxbgen -m py_schema_module -u schema.xsd

然后,我编写了以下脚本来解析我称为 example.xml 的 XML 文件:

#!/usr/bin/env python2.7                                                        

import py_schema_module                                                         

if __name__ == "__main__":                                                      
    with open("example.xml", "r") as f:                                         
        py_schema_module.CreateFromDocument(f.read())

我使用该脚本来确定 example.xml 语法的合法性。例如,以下 example.xml 文件具有每个架构的合法语法:

<outertag>                                                                      
    <innertag0></innertag0>                                                     
    <innertag1></innertag1>                                                     
</outertag>

这样做也是如此:

<outertag>                                                                      
    <innertag1></innertag1>                                                     
    <innertag0></innertag0>                                                     
</outertag>

但是,以下语法是非法的:

<outertag>                                                                      
    <innertag1></innertag1>                                                     
    <innertag0></innertag0>                                                     
    <innertag1></innertag1>                                                     
</outertag>

这是这样的:

<outertag>                                                                      
    <innertag0></innertag0>                                                     
    <innertag1></innertag1>                                                     
    <innertag0></innertag0>                                                     
</outertag>

我可以写innertag0,然后写innertag1。我也可以写innertag1,然后写innertag0。我也可以任意重复innertag0 和innertag1 的实例(为简洁起见未显示示例)。但是,我不能做的是在 innertag0 和 innertag1 之间切换。

假设我希望格式支持此功能。我应该如何更改我的 XML 模式文件?

4

2 回答 2

0

无论 innertag(0|1) 元素的顺序如何,以下 XML Schema (XSD) 1.0 都应涵盖您的用例。minOccurs两者的默认值为maxOccurs1。

有用的链接:XML 模式,为什么 xs:group 不能是 xs:all 的子级?

XML

<outertag>
    <innertag1></innertag1>
    <innertag0></innertag0>
</outertag>

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="outertag">
        <xs:complexType>
            <xs:all>
                <xs:element name="innertag0" type="xs:string"/>
                <xs:element name="innertag1" type="xs:string"/>
            </xs:all>
        </xs:complexType>
    </xs:element>
</xs:schema>
于 2020-03-02T22:36:34.413 回答
0

您的模式处理器似乎没有对规范进行非常仔细的检查。

如果我尝试使用 Saxon 将您的架构处理为 XSD 1.0 架构,它会告诉我有四个错误:

Error at xs:element on line 3 column 59 of test.xsd:
  Attribute @minOccurs is not allowed on element <xs:element>
Error at xs:element on line 3 column 59 of test.xsd:
  Attribute @maxOccurs is not allowed on element <xs:element>
Error at xs:all on line 5 column 15 of test.xsd:
  Within <xs:all>, an <xs:element> must have @maxOccurs equal to 0 or 1
Error at xs:all on line 5 column 15 of test.xsd:
  Within <xs:all>, an <xs:element> must have @maxOccurs equal to 0 or 1
Schema processing failed: 4 errors were found while processing the schema

前两个是这样说的,minOccurs并且maxOccurs不允许在全局元素声明中使用。

后两个说maxOccurs必须在 1 内xs:all- XSD 1.0 不允许元素在内容模型为xs:all. 您的处理器告诉您这是 XML 实例中的错误,但实际上是您的架构中的错误。

XSD 1.1 确实允许在xs:all. @minOccurs如果我通过删除and来更正全局元素声明@maxOccurs,则该模式现在在 XSD 1.1 下有效,并允许您遇到问题的交错实例示例。

于 2020-03-03T00:10:30.933 回答