灵活的递归 XML 模式
Flexible recursive XML schema
我正在尝试为此示例创建验证架构 XML。我已经尝试使用递归定义,但找不到合适的方法。请注意,IF 和 ELSE 元素可以嵌套任意次数,并且 ACTIONx 元素可以以任意顺序出现。另请注意,每个元素都有自己可能不同的属性。
<?xml version="1.0" encoding="utf-8"?>
<KEYPRESS Buffer="1">
<ACTION1 Index="15" />
<IF Condition="0">
<IF Condition="1">
<ACTION1 Index="14" />
<ELSE>
<ACTION2 Measure="whatever" />
</ELSE>
</IF>
<IF Condition="2">
<IF Condition="5">
<ACTION2 Measure="whatelse" />
<ACTION3 Type="Flag" />
</IF>
<ELSE>
<ACTION1 Index="0" />
<ACTION3 Type="Other" />
<IF Condition="1">
<ACTION3 Type="Flag" />
</IF>
</ELSE>
</IF>
</IF>
</KEYPRESS>
我们将不胜感激。
*** 编辑 ***
非常感谢Michael Kay,优秀的解决方案!
我在这里发布生成的架构,以防有人感兴趣。
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2021 (https://www.liquid-technologies.com) -->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="INSTRUCTION" abstract="true"/>
<xs:element name="ACTION1" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:attribute name="Index" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="ACTION2" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:attribute name="Index" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="ACTION3" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:attribute name="Type" type="xs:string" use="required" />
<xs:attribute name="Index" type="xs:string" use="required" />
<xs:attribute name="Value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="IF" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:sequence>
<xs:element ref="INSTRUCTION" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="ELSE" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="Type" type="xs:string" use="required" />
<xs:attribute name="Index" type="xs:string" use="required" />
<xs:attribute name="Condition" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="KEYPRESS" >
<xs:complexType>
<xs:sequence>
<xs:element ref="INSTRUCTION" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="KeySeq" type="xs:string" use="required" />
<xs:attribute name="Buffer" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="ELSE" >
<xs:complexType>
<xs:sequence>
<xs:element ref="INSTRUCTION" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我认为您不能定义具有可变元素名称的架构。
一个 element declaration 需要一个名字。该值是 xs:NCName
类型,它只是一个字符串而不是模式。为了编写模式,您必须找出动作元素的最大数量。而且您必须为每个元素定义一个 complexType。我认为你不想这样做。
您 XML 文件是由对 XML 了解不多的人设计的。你最好告诉他,格式必须重新设计。而不是
<ACTION1 ...>
使用
<ACTION N="1" ...>
模式验证会很容易。
这种结构就是置换组的用途。
定义一个抽象元素INSTRUCTION
,然后定义IF
、ACTION1
、ACTION2
和ACTION3
作为[的替换组成员=10=],每个都有自己的类型定义,定义了允许的属性。 KEYPRESS
和 ELSE
的内容模型显示为 INSTRUCTION*
(0 个或多个指令的序列),IF
的内容模型显示为 (INSTRUCTION*, ELSE?)
(0 个或多个指令的序列,后跟一个 ELSE
)。
(ELSE
不是替换组的成员,因为它不能出现在指令出现的任何地方)。
我正在尝试为此示例创建验证架构 XML。我已经尝试使用递归定义,但找不到合适的方法。请注意,IF 和 ELSE 元素可以嵌套任意次数,并且 ACTIONx 元素可以以任意顺序出现。另请注意,每个元素都有自己可能不同的属性。
<?xml version="1.0" encoding="utf-8"?>
<KEYPRESS Buffer="1">
<ACTION1 Index="15" />
<IF Condition="0">
<IF Condition="1">
<ACTION1 Index="14" />
<ELSE>
<ACTION2 Measure="whatever" />
</ELSE>
</IF>
<IF Condition="2">
<IF Condition="5">
<ACTION2 Measure="whatelse" />
<ACTION3 Type="Flag" />
</IF>
<ELSE>
<ACTION1 Index="0" />
<ACTION3 Type="Other" />
<IF Condition="1">
<ACTION3 Type="Flag" />
</IF>
</ELSE>
</IF>
</IF>
</KEYPRESS>
我们将不胜感激。
*** 编辑 *** 非常感谢Michael Kay,优秀的解决方案! 我在这里发布生成的架构,以防有人感兴趣。
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2021 (https://www.liquid-technologies.com) -->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="INSTRUCTION" abstract="true"/>
<xs:element name="ACTION1" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:attribute name="Index" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="ACTION2" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:attribute name="Index" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="ACTION3" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:attribute name="Type" type="xs:string" use="required" />
<xs:attribute name="Index" type="xs:string" use="required" />
<xs:attribute name="Value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="IF" substitutionGroup="INSTRUCTION">
<xs:complexType>
<xs:sequence>
<xs:element ref="INSTRUCTION" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="ELSE" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="Type" type="xs:string" use="required" />
<xs:attribute name="Index" type="xs:string" use="required" />
<xs:attribute name="Condition" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="KEYPRESS" >
<xs:complexType>
<xs:sequence>
<xs:element ref="INSTRUCTION" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="KeySeq" type="xs:string" use="required" />
<xs:attribute name="Buffer" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="ELSE" >
<xs:complexType>
<xs:sequence>
<xs:element ref="INSTRUCTION" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我认为您不能定义具有可变元素名称的架构。
一个 element declaration 需要一个名字。该值是 xs:NCName
类型,它只是一个字符串而不是模式。为了编写模式,您必须找出动作元素的最大数量。而且您必须为每个元素定义一个 complexType。我认为你不想这样做。
您 XML 文件是由对 XML 了解不多的人设计的。你最好告诉他,格式必须重新设计。而不是
<ACTION1 ...>
使用
<ACTION N="1" ...>
模式验证会很容易。
这种结构就是置换组的用途。
定义一个抽象元素INSTRUCTION
,然后定义IF
、ACTION1
、ACTION2
和ACTION3
作为[的替换组成员=10=],每个都有自己的类型定义,定义了允许的属性。 KEYPRESS
和 ELSE
的内容模型显示为 INSTRUCTION*
(0 个或多个指令的序列),IF
的内容模型显示为 (INSTRUCTION*, ELSE?)
(0 个或多个指令的序列,后跟一个 ELSE
)。
(ELSE
不是替换组的成员,因为它不能出现在指令出现的任何地方)。