我需要为XML文件创建一个非常灵活的模式.它必须满足以下要求:
快速举例:
XML
<person>
<age></age>
<lastname></lastname>
<height></height>
</person>
Run Code Online (Sandbox Code Playgroud)
我在XSD上的尝试:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" minOccurs="0" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
现在我的XSD满足要求1和3.它不是有效的模式,但是,如果firstname和lastname都是可选的,那么它不满足要求2,并且订单是固定的,这不符合要求4.
现在我只需要验证我的XML.我对以任何方式执行此操作的建议持开放态度,无论是以.NET 3.5编程还是其他类型的架构等.
谁能想到满足所有4个要求的解决方案?
如果名称元素是可选的,则无法解决您的需求号3,因为您的架构会违反唯一的粒子归因规则(基本上,处理器将不知道是否针对firstname或针对any来验证firstname).
就验证而言,您不限于单个模式.如果您可以在不同的命名空间中使用两个模式,则可以执行以下操作:
架构一 - 允许任何事情:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="document">
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
模式二 - 为某些元素添加特定验证:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://other" xmlns="http://other">
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
然后确保您的实例文档的xsi:include引用两个模式.
今天我想了很多这个问题。我正在考虑这条xs:all规则使得 XML 数据库存储具有非结构化“CMS”(如数据)的文档,同时验证数据有多么困难。
然后我突然想到,XHTML 允许非常灵活地排列嵌套元素,无论您需要用什么顺序来标记页面。
以下是 XHTML 1.1 架构的摘录:
<xs:group name="InlForm.class">
<xs:choice>
<xs:element ref="input"/>
<xs:element ref="select"/>
<xs:element ref="textarea"/>
<xs:element ref="label"/>
<xs:element ref="button"/>
</xs:choice>
</xs:group>
<xs:group name="Inline.extra">
<xs:choice/>
</xs:group>
<xs:group name="Ruby.class">
<xs:sequence>
<xs:element ref="ruby"/>
</xs:sequence>
</xs:group>
<!--
Inline.class includes all inline elements,
used as a component in mixes
-->
<xs:group name="Inline.class">
<xs:choice>
<xs:group ref="InlStruct.class"/>
<xs:group ref="InlPhras.class"/>
<xs:group ref="InlPres.class"/>
<xs:group ref="I18n.class"/>
<xs:group ref="Anchor.class"/>
<xs:group ref="InlSpecial.class"/>
<xs:group ref="InlForm.class"/>
<xs:group ref="Ruby.class"/>
<xs:group ref="Inline.extra"/>
</xs:choice>
</xs:group>
<xs:group name="Heading.class">
<xs:choice>
<xs:element ref="h1"/>
<xs:element ref="h2"/>
<xs:element ref="h3"/>
<xs:element ref="h4"/>
<xs:element ref="h5"/>
<xs:element ref="h6"/>
</xs:choice>
</xs:group>
Run Code Online (Sandbox Code Playgroud)
它们本质上是递归地嵌套组的选择。我想写这篇文章的人正在一个安全的机构中度过余生,每天接受几次强制药物治疗。
我希望这有帮助。我认为这说明了超级灵活模式是如何在 XSD 1.0 中“真正”完成的。
编辑-它有效!您可以创建所有其他组的“主”组,并使用此示例ListItem元素定义来允许以任何顺序连续嵌套元素。确保ListItem也包含在组中,以便递归有效。
<xs:element name="ListItem">
<xs:complexType>
<xs:sequence>
<xs:group ref="content:any.mix" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
所以我的any.mix小组看起来像这样:
<xs:group name="any.mix">
<xs:choice>
<xs:group ref="content:item.class" />
<xs:group ref="content:media.class" />
<xs:group ref="content:data.class" />
<xs:group ref="content:list.class" />
</xs:choice>
</xs:group>
Run Code Online (Sandbox Code Playgroud)
每个“类”组都包含更多的组选择,依此类推,直到它们最终到达元素,如果您愿意,可以是叶级实际标签。
组本身不应该有循环引用;“技巧”在于该any.mix组的无限出现,即它是一个具有无限根选择的选择树。
卢克