2010-04-07 79 views
4

我需要为XML文件创建一个非常灵活的模式。它必须满足以下要求:创建'灵活'XML模式

  1. 验证,我们需要是存在,并知道
  2. 验证一些元素是可选的确切结构的一些元素,我们知道的
  3. 确切结构允许任何其他元件
  4. 允许它们以任何顺序

快速例如:

XML

<person> 
    <age></age> 
    <lastname></lastname> 
    <height></height> 
</person> 

我在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> 

现在我的XSD满足要求1和3,它不是一个有效的模式。然而,如果这两个名字和姓氏是可选的,因此它不不符合要求2,并且订单是固定的,不符合要求4.

现在我需要的是验证我的XML。我愿意以任何方式提出建议,无论是以.NET 3.5编程式,另一种架构模式等。

任何人都可以想到满足所有4个要求的解决方案吗?

回答

1

今天我在想这个问题很多。我正在考虑这个规则如何使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> 

他们基本上是群体巢选择,递归。我想这个写这篇文章的人会在接下来的日子里生活在一个安全的机构里,一天接受几次强制服药。

我希望这会有所帮助。我认为这说明了如何在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> 

所以我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> 

而且每个“类”组都包含组的又更多的选择,等等等等,直到他们最终打元素,如果你喜欢的话,叶级别的实际标签。

该组本身不应该有循环引用; “招数”在any.mix组的无限次出现中,即其具有无限根选择的选择树。

Luke

+0

令人惊叹的解决方案,感谢分享! – 2014-08-22 08:15:39

+0

为了完整起见,我应该添加两点:a)它不是你所有梦想的答案,为了满足上面的所有要求,你可能需要添加额外的包含元素,我花了一个小时,放弃了,所以这个答案是以解决“超灵活”的部分b)如果你知道你的验证器是XSD1.1(稀有),那么'xs:all'现在等同于'xs:sequence'的宽松顺序,即它们删除了糟糕的“只有一个子元素“规则毁了XSD给我们所有人。 – 2014-08-22 09:33:13

6

如果名称元素是可选的,则您的需求编号3无法解决,因为您的模式会违反唯一的粒子归因规则(基本上,处理器不知道是否要根据名字或反对任何名称验证名字)。

就验证而言,您并不局限于单个模式。如果你确定在不同的命名空间中使用两种模式,你可以这样做:

架构一个 - 让任何东西:

<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> 

模式2 - 添加特定的验证了一些元素:

<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> 

然后确保你的实例文档的xsi:include引用两个模式。

+0

但仍然如何满足要求1?如果我使用多个模式,我如何要求'lastname'元素始终存在? – 2011-12-07 09:28:58