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