为什么这是不确定性,以及如何解决它?
<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>
但可以用任一端。
模式是不确定性时有具有相同元素开始两个分支-使你不能告诉采取哪个分支,而不该元素后向前看。 一个简单的例子是ab|ac
-当你看到a
,你不知道要采取的分支。 For循环的“分支”是是否重复循环,或继续后。 这方面的一个例子是a*a
-一旦你在循环,你读了a
,你不知道是否重复循环,或继续。
看着你的榜样模式,想象它刚刚解析的<till>
,现在它需要解析<from>
。 你可以用它解析<from><till>
循环或最终<from>
。 你不能告诉使用哪个分支,只需通过查看<from>
。 你只能告诉进一步寻求批准。
坏消息:我觉得你的榜样模式是一种非常罕见的一个,这是不可能的确定性表达!
以下是XML文档要接受(我使用的每个元素,其中一个字母a
= <from>...</from>
和b
= <to>...</to>
:
*empty*
a
ab
aba
abab
ababa
ababab
...
......你的想法。 问题是,任何字母可以是序列中的最后一个字母,也可以是循环的一部分。 有没有办法知道它会,除了通过在下面这封信找反超。 由于“确定性”是指,你不这样做前瞻(顾名思义),要不能确定性表达的语言。
简化您的架构,它尝试类似的做法(ab)*a?
-但两个分支开始a
。 另一种方法是a(ba)*b?
-现在两个分支开始b
。 我们赢不了!
技术上,集架构将接受所有文件被称为该模式的语言 。 如果没有确定的模式存在可以表达的语言, 语言被称为“一个暧昧”。
对于一个理论上的讨论,看到一系列的布吕格曼-克莱因纸(如确定性则语言和一不含糊则语言 )。 她包括一个明确的语言正式测试。
这是你的代码的一个简单的编辑; 我还没有尝试过:
<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'
允许两个终止序列“直到”秒。