2010-04-07 88 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