为什么这是不确定的以及如何解决它?
<xs:element name="activeyears">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="1">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element ref="from" minOccurs="1" maxOccurs="1"/>
<xs:element ref="till" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
<xs:element ref="from" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
这应该是指<activeyears>
为空或包含<from><till>
的序列,该序列以<from>
开头,但可以以其中任何一个结尾。
答案 0 :(得分:7)
当有两个以相同元素开头的分支时,模式是非确定性的 - 因此,如果不在该元素之后向前看,则无法分辨哪个分支。一个简单的示例是ab|ac
- 当您看到a
时,您不知道要采用哪个分支。对于循环,“分支”是重复循环,还是继续循环。一个例子是a*a
- 一旦你进入循环,你读了一个a
,你不知道是重复循环,还是继续。
查看您的示例模式,假设它刚刚解析了<till>
,现在需要解析<from>
。您可以使用<from><till>
循环或解析最终<from>
。您只能通过查看<from>
来判断使用哪个分支。你只能进一步展望未来。
坏消息:我认为您的示例架构非常罕见,确定性地表达不可能!
以下是您要接受的XML文档(我为每个元素使用一个字母,其中a
= <from>...</from>
和b
= <to>...</to>
:< / p>
*empty*
a
ab
aba
abab
ababa
ababab
...
...你明白了。问题是任何字母都可以是或序列中的最后一个字母,它可以是循环的一部分。没有办法告诉它会是什么,除非通过查看以下信件。由于“确定性”意味着你没有这样做(根据定义),你想要的语言无法确定性地表达。
简化您的架构,它会尝试类似于(ab)*a?
的方法 - 但两个分支都以a
开头。另一种方法是a(ba)*b?
- 现在两个分支都以b
开头。我们不能赢!
从技术上讲,架构将接受的所有文档集称为架构的语言。如果不存在可以表达语言的确定性模式,则语言称为“一个模糊的”。
有关理论讨论,请参阅Bruggemann-Klein撰写的一系列论文(例如 Deterministic Regular Languages 和 One-Unambiguous Regular Languages )。 她包括对一种明确的语言的正式测试。
答案 1 :(得分:0)
这是对代码的简单编辑;我没有尝试过:
<xs:element name="activeyears">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="1">
<xs:element ref="from" minOccurs="1" maxOccurs="1"/>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element ref="till" minOccurs="1" maxOccurs="1"/>
<xs:element ref="from" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
一些背景知识:XML模式是一种非常简单的语法,模式处理器是一种解析器,它尝试将此语法的规则应用于输入文件。然而,与传统编译器使用的解析器不同,XML模式没有前瞻性。因此,您不能拥有两个共享相同初始令牌集(规则名称)的规则。
所以,我做了具体的改变:
sequence
保持不变;它控制“空或具有特定内容”的要求。element
,显式出现次数minOccurs
。minOccurs='0'
进行的第二次编辑允许两个“直到”的终止序列。