<!-- /*<! [CDATA[*/ body { color: #000; background-color: #fff; margin: 0px 10%; min-width: 720px; font-family: Verdana, sans-serif; counter-reset: chapter section subsection subsubsection paragraph lchapter lsection lsubsection lsubsubsection lparagraph} div.footnote { border-left: 1px solid #000; margin-left: 0em; clear: both } div.ftext { position: relative; margin-left: 50px } div.fnumber { float: left; width: 40px; padding: 0em; margin-left: 0.5em; margin-top: 0em } div.fnumber a { margin: 0px; padding: 0px } div.ctext { position: relative; margin-left: 100px } div.cnumber { float: left; width: 90px; padding: 0em; margin-left: 0.5em; margin-top: 0em } div.cnumber a { margin: 0px; padding: 0px } div.tip { border: 2px solid #0d0; margin: 0.5em 2em 1em 2em; padding: 0em 1em } div.warning, div.caution, div.danger, div.error { border: 2px solid #f00; margin: 0.5em 2em 1em 2em; padding: 0em 1em } div.note, div.hint, div.important { border: 2px solid #000; margin: 0.5em 2em 1em 2em; padding: 0em 1em } div.figure { display: block; padding: 1em; width: 400px; clear: both} div.topic { margin: 2em } div.vstsidebar, div.sidebar { border: 2px solid #aaa; color: #000; background-color: #ffffee; float: right; width: 40%; margin-left: 1em; margin-right: -1em; padding: 1em } span.strike { text-decoration: line-through } span.big { font-size: large } span.small { font-size: small } span.title { font-style: italic } span.notetitle { font-size: large; font-weight: 900; font-family: Verdana, sans-serif } p.toc { font-size: large; font-weight: 900 } p.notesubtitle { font-weight: 900; font-family: Verdana, sans-serif } p.attribution { font-style: italic; margin-left: 8em; text-indent: -1.4em } .vstright { float: right; margin: 1em } .vstleft { float: left; margin: 1em } .vstcenter { margin: 1em auto } blockquote.pull { font-size: large } p.rubric { font-size: large; margin-left: 2em } dd.normal { margin-bottom: 0.5em } dt.option { float: left; margin: 0em 0em 5px 2em; padding: 0px; font-family: monospace } dd.option { padding: 0px; margin: 0em 0em 5px 10em; text-indent: 0.5em } dd.option > p { margin: 0px } dd.normal > p { margin: 0px } table { border-collapse: collapse; margin: 0.5em 0em } thead, tfoot { text-align: center; font-weight: bold } td { border: 1px solid #000; padding: 0.25em; _top: 0%; vertical-align: top } td blockquote p{ margin: 0px; padding: 0px} td blockquote { margin: 0px; padding: 0px} table.vstbless td { border: 0px solid #000; padding: 0.25em; _top: 0%; vertical-align: top } td > p { margin: 0px } table.field { border: 0px solid #000; margin-left: 2em; padding: 0.25em; _top: 0%; vertical-align: top } td.fkey { font-weight: 900 } td.fval { border: 0px solid #000; padding: 0.25em; _top: 0%; vertical-align: top } td.fkey { font-weight: 900; border: 0px solid #000; padding: 0.25em; _top: 0%; vertical-align: top } td.fdkey { text-align: center; font-weight: 900 } td.fdval { text-align: center; font-style: italic } td.fakey { text-align: center; font-weight: 900 } td.faval { border: 0px solid #000; padding: 0.25em; _top: 0%; vertical-align: top } hr { width: 100%; margin: 1.5em auto } h1 { text-align: center; clear: both } h2, h3, h4, h5, h6 { text-align: left; margin-top: 1em; clear: both } h2 { counter-reset: section subsection subsubsection paragraph } h3 { counter-reset: subsection subsubsection paragraph } h4 { counter-reset: subsubsection paragraph } h5 { counter-reset: paragraph } h1 a { color: #000; background-color: transparent } h2 a { color: #000; background-color: transparent } h3 a { color: #000; background-color: transparent } h4 a { color: #000; background-color: transparent } h5 a { color: #000; background-color: transparent } h6 a { color: #000; background-color: transparent } p.subh1 { text-align: center; font-size: 120%; font-variant: small-caps } p.subh2, p.subh3, p.subh4, p.subh5, p.subh6 { text-align: left; font-size: 120%; font-variant: small-caps } h2:before { content: counter(chapter)" "; counter-increment: chapter } h3:before { content: counter(chapter)"."counter(section)" "; counter-increment: section } h4:before { content: counter(chapter)"."counter(section)"."counter(subsection)" "; counter-increment: subsection } h5:before { content: counter(chapter)"."counter(section)"."counter(subsection)"."counter(subsubsection)" "; counter-increment: subsubsection } h6:before { content: counter(chapter)"."counter(section)"."counter(subsection)"."counter(subsubsection)"."counter(paragraph)" "; counter-increment: paragraph} li.h1 { margin-left: 0em } li.h2 { margin-left: 1em; counter-reset: lsection lsubsection lsubsubsection lparagraph } li.h3 { margin-left: 2em; counter-reset: lsubsection lsubsubsection lparagraph } li.h4 { margin-left: 3em; counter-reset: lsubsubsection lparagraph } li.h5 { margin-left: 4em; counter-reset: lparagraph } li.h2:before { content: counter(lchapter)" "; counter-increment: lchapter } li.h3:before { content: counter(lchapter)"."counter(lsection)" "; counter-increment: lsection } li.h4:before { content: counter(lchapter)"."counter(lsection)"."counter(lsubsection)" "; counter-increment: lsubsection } li.h5:before { content: counter(lchapter)"."counter(lsection)"."counter(lsubsection)"."counter(lsubsubsection)" "; counter-increment: lsubsubsection } li.h6:before { content: counter(lchapter)"."counter(lsection)"."counter(lsubsection)"."counter(lsubsubsection)"."counter(lparagraph)" "; counter-increment: lparagraph} li.h6 { margin-left: 5em } ol, ul { margin-bottom: 0.5em; margin-top: 0.5em } ol.loweralpha { list-style-type: lower-alpha } ol.upperalpha { list-style-type: upper-alpha } ol.lowerroman { list-style-type: lower-roman } ol.upperroman { list-style-type: upper-roman } ol.decimal { list-style-type: decimal } ul.square { list-style-type: square } ul.circle { list-style-type: circle } ul.disc { list-style-type: disc } li > p { margin: 0em } img { border: 1px solid #000; padding: 0em; display: block; margin: 1em auto } img.inline { border: 1px solid #000; padding: 0em; margin: 0em; display: inline } pre { color: #000; background-color: #eee; margin-left: 2em; clear: both; overflow: auto } div.unknown { font-family: monospace; color: #000; background-color: #fff; margin: 1em; padding: 1em; clear: both; border: 3px solid red} pre.quoted { color: #000; background-color: #eee; margin-left: 0em; clear: both; overflow: auto } pre.rawlatex { color: #000; background-color: #ddd; border: 1px solid #000; padding: 0.1em; clear: both; overflow: auto } pre.address { font-family: Verdana, sans-serif; display: inline; margin: 0px; color: #000; background-color: #fff; overflow: auto } span.target { text-decoration: underline } div.vstfooter hr { width: 100%; margin: 0px } div.vstfooter p { margin: 0px } /*]]>*/ -->
水木XML版(http://XML.board.newsmth.net/)上曾有网友提出了下面的问题:
发信人: cell (汤锅), 信区: XML 标 题: 请教个XSD的问题,多个无序元素 发信站: 水木社区 (Mon Dec 21 14:29:58 2009), 转信
在设计一个XSD的Schema,有个问题请教一下:
现在我有3个元素,希望它们以任意顺序和个数出现在一个复合类型里面,这个类型应 该如 何定义呢?试了下用sequence或者all好像都不行。
譬如下面这个XML例子,它的schema应该如何定义呢?
<TestElement>
-
<A/> <B/> <C/> <B/> <A/> <C/> </TestElement>
这类问题经常会在XML版上出现,在stackoverflow上也出现过类似的问题讨论( http://stackoverflow.com/questions/839079/middle-way-between-xsd-all-and-xsd-sequence#839110),但似乎也没得出结论。大家对无序元素的观点基本可以归纳为以下三种:
-
XSD的设计思想中摒弃了无序元素这种展现方式,所以sequence下元素属性有序,all下元素最多出现一次;
-
此问题现在还处于无解阶段,XSD 1.X标准将会解决;
-
添加一个元素将同名元素包装起来,例如上例中添加一个As元素用来包装A元素,形式如下:
<As>
-
<A>...</A> <A>...</A> ... ... </As>
实际上我在项目也遇到过此类问题,我采取的第三种解决方式,实际上这也是大多数人采用的方法。或许W3C并不提倡无序元素这种数据组织方式,所以这个问题没有明显的解决办法,但W3C也没有完全摒弃这种设计方式,而XSD标准是出了名的复杂,不能奢望通过研读XSD标准文档来找到解决之道。怎么办? 无意之间,我在水木XML版看到下面的帖子:
发信人: gmnicx (Mr.Zhuang|2010 完美毛毛), 信区: XML 标 题: Re: 使用choice标签的时候,下列需求如何实现 发信站: 水木社区 (Tue Jan 5 17:32:46 2010), 转信
明白了,原来occurs要写到choice标签里面 【 在 gmnicx (Mr.Zhuang|2010 完美毛毛) 的大作中提到: 】 : choice组有若干可能出现(可能不出现,也可能一个出现多次) : 但要求总数至少出现一次 : 例如 : ...................
原来choice可以加 occurs属性,那么无序元素的问题便迎刃而解了,且看下面的XSD:
<?xml version="1.0" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="TestElement"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="A" type="xs:anyType"/> <xs:element name="B" type="xs:anyType"/> <xs:element name="C" type="xs:anyType"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema>
choice加上两个Occurs属性,无序元素的问题到此便宣告解决了。 且慢,从上面的故事,我明白了两个道理:
1.洋人的讨论未必出真知,对于这个问题,stackoverflow并没给出结论。
2.人民群众的力量是无穷的。网络上的论坛、BBS、博客都提供了交流平台,无谓菜鸟还是专家,都可以在这些平台自由发表自己的见解,而解决问题的方法往往不是出自教堂里的大主教,而是来源于每个网民的点滴观点,这正如点滴之水能汇成江河。