Xsd 如何在XML模式中实现这一点?
这是我想要得到的XML:Xsd 如何在XML模式中实现这一点?,xsd,Xsd,这是我想要得到的XML: <root> <A> <C>asd</C> <D>asd</D> <E>asd</E> </A> <B> <C>asd</C> <D>asd</D> <E>asd</E
<root>
<A>
<C>asd</C>
<D>asd</D>
<E>asd</E>
</A>
<B>
<C>asd</C>
<D>asd</D>
<E>asd</E>
<F>asd</F>
</B>
</root>
自闭症
自闭症
自闭症
自闭症
自闭症
自闭症
自闭症
这里还有一些限制:
- 可以有多个A和B元素,顺序任意
- A和B的内容完全相同,只是B也可能包含元素F李>
- C、 D、E和F可以任何顺序出现
- E可以出现多次李>
- C和D可以出现0或1次李>
- F必须正好出现1次
这可能吗?另一方面,为什么XML模式在定义如此简单的场景时如此笨拙?这解决了大多数情况,但更难的是允许任何订单部分。由于您处理的是复杂类型,因此主要使用Sequence命令。还有其他一些,但它们也不适用于您的场景。另外,虽然从纯xml的角度来看这似乎很简单,但从验证的角度来看却不简单。需要注意的主要问题是,按照构建此文档的方式,您必须将所有
可能有一些更复杂的方法来做你想做的事情,但这至少给了你基本的模式
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="Avalue">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="C" type="xs:string"/>
<xs:element minOccurs="0" maxOccurs="1" name="D" type="xs:string"/>
<xs:element minOccurs="0" maxOccurs="unbounded" name="E" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Bvalue">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="C" type="xs:string"/>
<xs:element minOccurs="0" maxOccurs="1" name="D" type="xs:string"/>
<xs:element minOccurs="0" maxOccurs="unbounded" name="E" type="xs:string"/>
<xs:element minOccurs="1" maxOccurs="1" name="F" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="A" type="Avalue"/>
<xs:element minOccurs="0" maxOccurs="unbounded" name="B" type="Bvalue"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
若您只是在寻找代码完成(正如您在评论中提到的),那个么只需将每种类型定义为可能的子类型的无限选择。例如,对于B:
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="C" type="xs:string"/>
<xs:element name="D" type="xs:string"/>
<xs:element name="E" type="xs:string"/>
<xs:element name="F" type="xs:string"/>
</xs:choice>
另一方面,为什么XML模式在定义如此简单的场景时如此笨拙
部分原因是稀疏XML/DTD通过将特性保持在最低限度并对简单处理器友好而击败了丰富的SGML/DTD。因此,XML模式希望比SGML更接近XML。如果C、D、E和F子级的顺序没有传递任何信息,那么实际上,在许多情况下,为它们指定一个固定的顺序更简单,正如OP在另一个答案的评论中所建议的那样
在XSD1.0中,允许C、D和E以任意顺序出现,并带有指定的基数约束,需要一个相当详细的内容模型。使用正则表达式语法(并允许空白以确保易读性),将
(C ((DE+)|(E+(DE*)?)) )
|
(D ((CE+)|(E+(CE*)?)) )
|
(E+ ((DE*(CE*)?)|(CE*(DE*)?))? )
由于B的内容模型为该语言的有限状态自动机中每个状态必须携带的信息量增加了一位(即“我们看到F了吗?”),因此它毫不奇怪地将最小FSA的大小增加了一倍,并使内容模型更大:
C ( (D ((E+FE*)|(FE+)) )
| (E+ ((DE*FE*)|(FE*(DE*)?)))
| (F ((DE+)|(E+DE*)))
)
D ( (C ((E+FE*)|(FE+)))
| (E+ ((CE*FE*)|(FE*(CE*)?)))
| (F ((CE+)|(E+CE*)))
)
E+ ( (CE* ((DE*FE*)|(FE*(DE*)?)))
| (DE* ((CE*FE*)|(FE*(CE*)?)))
| (FE* ((CE*(DE*)?)|(DE*(CE*)?))?)
)
F ( (C ((DE+)|(E+DE*)))
| (D ((CE+)|(E+CE*)))
| (E+ ((CE*(DE*)?)|(DE*(CE*)?))?)
)
这是一个有点乏味的工作,但它肯定是合法的XSD1.0,它捕获了OP描述的约束;因此,它表明说XSD1.0无法捕获约束是错误的。最能说明问题的是,不可能在XSD1.0中简洁地捕获OP的需求。这是XSD 1.0内容模型与DTD内容模型、正则表达式和XSD 1.0内容模型所基于的上下文无关语法的常规符号共享的属性
其他模式语言可以更简洁地处理这一点:在RELAXNG中,交错运算符使编码此类约束相对简单。在XSD 1.1中,对all
组的约束放宽使得捕获需求变得相当简单:
<xs:complexType name="CDE">
<xs:all>
<xs:element ref="C" minOccurs="0" maxOccurs="1"/>
<xs:element ref="D" minOccurs="0" maxOccurs="1"/>
<xs:element ref="E" minOccurs="1" maxOccurs="unbounded"/>
</xs:all>
</xs:complexType>
<xs:complexType name="CDEF">
<xs:complexContent>
<xs:extension base="CDE">
<xs:all>
<xs:element ref="F" minOccurs="1" maxOccurs="1"/>
</xs:all>
</xs:extension>
</xs:complexContent>
</xs:complexType>
这确实会使验证器的工作复杂化(以最简单的方式说:这意味着验证器的作者不能使用标准的教科书算法,因为标准教科书不包含交错运算符),但不管是好是坏,许多词汇设计者都不喜欢约束顺序,即使在顺序不传递任何信息的情况下,也不需要不受约束。你有没有已经尝试过的东西?我现在正在尝试一件事,但除此之外,我甚至在开始打字之前就放弃了其他一切……你说它很简单,但实际上从建模的角度来看,它是合理的复杂。虽然模式太冗长了。是的,但是定义了一个序列-不能在and标记中自由地包含C、D、E和F标记。这与当前XML模式的效果差不多。