XML元素的任何顺序,有些是必需的,有些则不是';T

XML元素的任何顺序,有些是必需的,有些则不是';T,xml,xsd,Xml,Xsd,我试图得到一个元素列表,这些元素可以按任何顺序排列。有些元素是必需的(最小值为1,最大值为1),有些元素是可选的,最大值为1,有些元素是可选的,任何数字都可以。这就是我所拥有的,XSD是有效的,但是当我去验证XML时,我试图实现的规则并没有被强制执行。例如,id不是必需的 <xsd:complexType name="feedType"> <xsd:annotation> <xsd:documentation>

我试图得到一个元素列表,这些元素可以按任何顺序排列。有些元素是必需的(最小值为1,最大值为1),有些元素是可选的,最大值为1,有些元素是可选的,任何数字都可以。这就是我所拥有的,XSD是有效的,但是当我去验证XML时,我试图实现的规则并没有被强制执行。例如,id不是必需的

<xsd:complexType name="feedType">
        <xsd:annotation>
            <xsd:documentation>
                The Atom feed construct is defined in section 4.1.1 of the format spec.
            </xsd:documentation>
        </xsd:annotation>
        <xsd:choice minOccurs="3" maxOccurs="unbounded">
            <xsd:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="generator" type="atom:generatorType" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="icon" type="atom:iconType" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="id" type="atom:idType" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="logo" type="atom:logoType" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="subtitle" type="atom:textType" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="title" type="atom:textType" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="updated" type="atom:dateTimeType" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="entry" type="atom:entryType" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attributeGroup ref="atom:commonAttributes"/>
    </xsd:complexType>

Atom提要构造在格式规范的第4.1.1节中定义。

选项
只允许其一个子元素出现在XML图形中。如果元素总是以相同的顺序排列,则似乎要使用
序列。如果顺序是可变的,则应使用
all
并将具有
maxOccurs=“unbounded”
的所有元素包装到包含列表元素中,因为
all
只允许其子元素出现1次或零次

编辑:

您应该从choice元素中删除minOccurs和maxOccurs。这只允许您强制执行3个选项,但不允许您指定它们是什么选项(包括多次重复同一元素)。我不知道你到底想强制执行什么,但那样做不会有效

编辑2:

您可以按如下方式创建列表包装器(以link元素为例):


在xml文档中,您可以(例如)将链接元素嵌套在链接列表中:

旧的:


...
...
...
...
新的:


...
...
...
...

我刚刚遇到了同样的问题,并查看了他们在应用程序中所做的工作。在
中也有相同的情况:
标题
是必需的,
基础
是可选的,然后允许有任意数量的
脚本
样式
链接
对象
元素

以下是他们所做的:首先,他们将可能出现多次的可选元素分组:

  <xs:group name="head.misc">
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="script"/>
        <xs:element ref="style"/>
        <xs:element ref="meta"/>
        <xs:element ref="link"/>
        <xs:element ref="object"/>
      </xs:choice>
    </xs:sequence>
  </xs:group>
这有点棘手。以类似正则表达式的伪代码编写,上面的代码如下所示:

misc=(script|style|meta|link|object)*
head=${misc}(title${misc}(base${misc})?|base${misc}title${misc})
因此,从技术上讲,它是有效的

然而,这需要在
选项
中放置所有可能的强制和可选元素的排列(中间有misc stuff)。对于
n
元素,这就是
n子节点。因此,对于带有
n=2的XHTML,它们的结果是
n=2
。对于
n=8
,它将是
n=40320

FWIW,以下是生成XSD的算法:

result=''
forall(可选任意计数元素作为元素)
结果+=“”
结果+=“”
结果+=“”
置换=getAllPermutations(强制元素+可选元素)
foreach(置换为p)
结果+=“”
foreach(p作为元素)
if(元素等参)
结果+=“”
结果+=“”
if(元素等参)
结果+=“”
结果+=“”
结果+=“”
返回结果

基本上,在使用XSD时不要这样做。它不是为这样的用例设计的

您可以改为使用其无序操作进行验证,或者如果您有需要XSD的合作伙伴,则可以强制执行任意顺序

中给出的atom提要架构使用RelaxNG的原因如下:

   atomFeed =
      element atom:feed {
         atomCommonAttributes,
         (atomAuthor*
          & atomCategory*
          & atomContributor*
          & atomGenerator?
          & atomIcon?
          & atomId
          & atomLink*
          & atomLogo?
          & atomRights?
          & atomSubtitle?
          & atomTitle
          & atomUpdated
          & extensionElement*),
         atomEntry*
      }

有关何时在XML中强制执行顺序的进一步讨论,请参阅。xsd:all下似乎只允许使用注释和元素,因此我不确定如何包装maxOccurs=“unbounded”元素。嗯,问题是我无法控制XML结构,实际上我们没有LinkedList容器元素的等价物。每个“链接”元素都与id处于同一级别。这是Atom标准。没有正式的XSD,我们正在尝试创建一个供自己使用的XSD,但仍然遵循Atom标准。然后需要使用序列,这意味着XML文档中的元素顺序需要保持不变。这就是我试图避免的,因为我希望元素能够以任何顺序排列,就像标准允许的那样。也许这是XSD的一个限制,我不能同时实现所有目标。是的,您可以约束元素顺序或使用列表包装元素。XSD是这样的,因为如果在一个给定的包含元素中,您能够拥有多个相同类型的元素,并且没有为元素设置顺序,那么您可以将单个元素类型的集合分散到该级别,并与其他类型的元素穿插在一起。这将使其不明确,其目的是拥有一个或多个给定类型的集合。+1,我只需要可以重复任意次数的元素,因此我使用了
而不是
  <xs:group name="head.misc">
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="script"/>
        <xs:element ref="style"/>
        <xs:element ref="meta"/>
        <xs:element ref="link"/>
        <xs:element ref="object"/>
      </xs:choice>
    </xs:sequence>
  </xs:group>
  <xs:sequence>
    <xs:group ref="head.misc"/>
    <xs:choice>
      <xs:sequence>
        <xs:element ref="title"/>
        <xs:group ref="head.misc"/>
        <xs:sequence minOccurs="0">
          <xs:element ref="base"/>
          <xs:group ref="head.misc"/>
        </xs:sequence>
      </xs:sequence>
      <xs:sequence>
        <xs:element ref="base"/>
        <xs:group ref="head.misc"/>
        <xs:element ref="title"/>
        <xs:group ref="head.misc"/>
      </xs:sequence>
    </xs:choice>
  </xs:sequence>
misc=(script|style|meta|link|object)*
head=${misc}(title${misc}(base${misc})?|base${misc}title${misc})
   atomFeed =
      element atom:feed {
         atomCommonAttributes,
         (atomAuthor*
          & atomCategory*
          & atomContributor*
          & atomGenerator?
          & atomIcon?
          & atomId
          & atomLink*
          & atomLogo?
          & atomRights?
          & atomSubtitle?
          & atomTitle
          & atomUpdated
          & extensionElement*),
         atomEntry*
      }