2010-09-02 65 views
4

使用XML模式限制嵌套在父元素中的子元素的深度是否可能?限制XSD中嵌套元素的深度

這裏的上下文是我從管理系統收集警報,我想提供一個XML文檔,它允許最終用戶定義一些規則,以便將警報過濾到UI中的文件夾中。我想限制嵌套文件夾的深度爲3,因此最終用戶無法嵌套數百個層次 - 因爲過濾到如此多的層次最終會導致應用程序崩潰。

我可以編寫一些代碼來處理這個問題,但是如果可能的話,在模式中定義這個代碼似乎是適當的。

例如,這將是罰款:

<group name="Folder 1"> 
     <group name="Folder 2"> 
      <group name="Folder 3"> 
       <group name="Folder 4"> 
       </group> 
      </group> 
     </group> 
    </group> 

這將是無效的,因爲文件夾5太深。

<group name="Folder 1"> 
     <group name="Folder 2"> 
      <group name="Folder 3"> 
       <group name="Folder 4"> 
        <group name="Folder 5"> 
        </group> 
       </group> 
      </group> 
     </group> 
    </group> 

我的模式看起來像這樣,但它不限制上面代碼片段的深度。

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="hierarchy"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="group" type="GroupType" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 

    <xs:complexType name="GroupType"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="group" type="GroupType" /> 
    </xs:sequence> 
    <xs:attribute name="name" type="xs:string" use="required" /> 
    <xs:attribute name="filterOn" type="xs:string" use="optional" /> 
    <xs:attribute name="operator" type="xs:string" use="optional" /> 
    <xs:attribute name="value" type="xs:string" use="optional" /> 
    </xs:complexType> 
</xs:schema> 

任何指針非常感謝!

回答

4

一個漂亮而簡單的解決方案在XML Schema中是不可用的(但是在其他語言中),但實際上可以通過嵌套整個東西來實現,我不建議這樣做。

所以,如果我是你,我會做兩件事情之一:

  1. 選擇XML模式(或擴展)的替代參見:http://en.wikipedia.org/wiki/XML_schema#XML_schema_languages(看看RELAX和Schematron)
  2. 在您的應用程序中進行深度檢查並拒絕它,如果depth > 3並使您的XML模式和應用程序的文檔中明確的行爲。從維基

報價約XML架構版本1.1(候選推薦):

通過XPath 2.0中表達式的裝置,以限定針對文檔內容斷言(從Schematron的借用一個想法)

的能力

< - 這樣做的深度很容易定義。

有關如何在XMLSchema的代表嵌套深度評論:

基本上,你可以這樣做以下(仍然建議在代碼中這樣做)。然後添加屬性,調整深度等(您可以重複使用屬性extensionrestrict,但我不是100%確定的)。這種方法可以得到相當討厭(指數),如果你允許多個類型的子元素:

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://somenamespace.com" 
      xmlns="http://somenamespace.com"> 

    <xs:element name="hierarchy"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="group" type="GroupTypeDepth0" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 

    <xs:complexType name="GroupTypeDepth0"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="group" type="GroupTypeDepth1" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="GroupTypeDepth1"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="group" type="GroupTypeDepth2" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="GroupTypeDepth2"/> 
</xs:schema> 

有效期:

<hierarchy xmlns="http://somenamespace.com"> 
    <group> 
    <group> 
     <group/> 
    </group> 
    </group> 
</hierarchy> 

無效:

<hierarchy xmlns="http://somenamespace.com"> 
    <group> 
    <group> 
     <group> 
     <group/> 
     </group> 
    </group> 
    </group> 
</hierarchy> 
+0

如何將我窩架構做到這一點?不幸的是,我必須使用XML模式,因爲由於許可考慮,我無法添加支持RELAX/Schematron所需的第三方庫(Java應用程序)。我可能最終不得不編寫一些非常不雅的代碼來支持這一點,即使架構解決方案很混亂,也可能是兩個弊端中較小的一個。 – tja 2010-09-03 12:37:40

+0

@tja看到更新:) – 2010-09-03 15:21:23

+0

完美,我把你的觀點放在優雅(或缺乏)上。 – tja 2010-09-03 16:24:34