4

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

这里的上下文是我从管理系统收集警报,我想提供一个 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

1 回答 1

4

XML Schema 中没有一个漂亮而简单的解决方案(但在其他语言中),但您实际上可以通过自己嵌套整个事情来实现它,我不推荐。

所以,如果我是你,我会做以下两件事之一:

  1. 选择 XML Schema 的替代方案(或扩展)请参阅:http ://en.wikipedia.org/wiki/XML_schema#XML_schema_languages (查看 RELAX 和 Schematron)
  2. 在您的应用程序中进行深度检查并拒绝它,depth > 3并在您的 XML 模式和应用程序的文档中明确该行为。

来自 Wiki 的关于 XML Schema 版本 1.1 的引述(候选推荐):

通过 XPath 2.0 表达式定义针对文档内容的断言的能力(从 Schematron 借来的想法)

<- 这将使深度很容易定义。

有关如何在 XMLSchema 中表示嵌套深度的评论

基本上您可以执行以下操作(仍然建议在代码中执行此操作)。然后您添加属性,调整深度等(您可以使用extensionor重用属性,restrict但我不是 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>
于 2010-09-02T19:04:16.497 回答