本文介绍了创建一个“灵活"的 XML 模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to create a schema for an XML file that is pretty flexible. It has to meet the following requirements:

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

快速示例:

XML

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

我对 XSD 的尝试:

My attempt at an 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.但是,如果 firstname 和 lastname 都是可选的,则它不是一个有效的架构,因此它不满足要求 2,并且顺序是固定的,这不符合要求 4.

Now my XSD satisfies requirements 1 and 3. It is not a valid schema however, if both firstname and lastname were optional, so it doesn't satisfy requirement 2, and the order is fixed, which fails requirement 4.

现在我只需要一些东西来验证我的 XML.我对任何方式的建议持开放态度,无论是在 .NET 3.5 中以编程方式还是其他类型的架构等.

Now all I need is something to validate my XML. I'm open to suggestions on any way of doing this, either programmatically in .NET 3.5, another type of schema etc.

谁能想出一个解决方案来满足所有 4 个要求?

Can anyone think of a solution to satisfy all 4 requirements?

推荐答案

我今天想了很多这个问题.我正在考虑这条 xs:all 规则有多难让 XML 数据库存储具有非结构化CMS"(如数据)的文档,同时还验证数据.

I was thinking about this problem a lot today. I was considering how hard this xs:all rule makes it for XML databases to store documents that have unstructured "CMS" like data, while also validating the data.

然后我突然想到,XHTML 允许以任何您需要标记页面的顺序非常灵活地安排嵌套元素.

Then it occurred to me that XHTML allows for very flexible arrangements of nested elements in whatever order you need to mark a page up with.

下面是 XHTML 1.1 模式的摘录:

So here's an excerpt from the XHTML 1.1 schema:

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

它们本质上是递归嵌套组的选择.我想写这篇文章的人是在一个安全的机构里度过余生,每天接受几次强制服药.

They essentially nest choices of groups, recursively. I imagine the person that wrote this is living out the rest of their days in a secure institution receiving forced medication several times a day.

我希望这会有所帮助.我认为这说明了超级灵活模式是如何在 XSD 1.0 中真正"完成的.

I hope this helps. I think this illustrates how super-flexi schemas are 'really' done in XSD 1.0.

编辑 - 有效!您可以创建所有其他组的主"组,并使用此示例 ListItem 元素定义来允许以任何顺序连续嵌套元素.确保 ListItem 也包含在组中,以便递归工作.

Edit - it works! You can make a 'master' group of all the other groups and use this example ListItem element definition to allow continuously nested elements in any order. Ensure ListItem is also included within a group so the recursion works.

  <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 组看起来像这样:

So my any.mix group looks like this:

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

每个类"组中的每一个都包含更多的组选择,依此类推,直到它们最终命中元素,如果您愿意,也可以是叶级实际标签.

And each of those "class" groups contain yet more choices of groups, and so on and so on until they eventually hit the elements, the leaf level actual tags if you like.

组本身不应有循环引用;技巧"在 any.mix 组的无限出现中,即它是一个具有无限根选择的选择树.

The groups themselves should not have circular references; the 'trick' is in the unbounded occurrences of the any.mix group, i.e. its a tree of choices with an unlimited root choice.

卢克

这篇关于创建一个“灵活"的 XML 模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 18:17