我正在开发一个描述消息结构的XML Schema(message.xsd
)。
以下是<message>
元素(根)的预期子元素:
<from>
:包含发件人的地址。发生0或1次。<to>
:包含收件人的地址。发生0次或更多次。<cc>
:包含副本中收件人的地址。发生0次或更多次。<subject>
:包含邮件的主题。发生0或1次。<body>
:包含邮件正文。发生0或1次。元素的顺序无关紧要,这意味着它们可以按任何顺序排列。
这是第一个简单的XML示例(message-1.xml
)必须有效:
$ xmllint --schema message.xsd message-1.xml
<?xml version="1.0"?>
<message xmlns="http://yugiohjcj.1s.fr/message">
<from>me@domain.com</from>
<to>you@domain.com</to>
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
</message>
message-1.xml validates
它有效!
这是第二个更复杂的XML示例(message-2.xml
)必须有效:
$ xmllint --schema message.xsd message-2.xml
<?xml version="1.0"?>
<message xmlns="http://yugiohjcj.1s.fr/message">
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<from>me@domain.com</from>
<to>you@domain.com</to>
<to>and-you@domain.com</to>
<cc>someone-else@domain.com</cc>
<cc>again-someone-else@domain.com</cc>
</message>
message-2.xml validates
它有效!
以下是第三个必须无效的XML示例(message-3.xml
):
$ xmllint --schema message.xsd message-3.xml
<?xml version="1.0"?>
<message xmlns="http://yugiohjcj.1s.fr/message">
<from>me@domain.com</from>
<from>someone-else@domain.com</from>
<to>you@domain.com</to>
<subject>How are you?</subject>
<subject>How are you again?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<body>Hello. How are you again? Thank you. Best regards.</body>
</message>
message-3.xml validates
但它有效! 这就是问题所在。
这是我的XML架构(message.xsd
):
$ cat message.xsd
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://yugiohjcj.1s.fr/message" targetNamespace="http://yugiohjcj.1s.fr/message" elementFormDefault="qualified">
<xs:element name="message">
<xs:complexType>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="from"/>
<xs:element name="to"/>
<xs:element name="cc"/>
<xs:element name="subject"/>
<xs:element name="body"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我想我需要在某处将maxOccurs
属性设置为值1
,或者我需要对<xs:sequence>
和<xs:choice>
元素进行不同的组合,但我没有找到了如何达到我的目标。
请知道如何修复此XML Schema?
谢谢。
最好的问候。
修改:好的,我使用Relax NG代替XSD 1.0找到了解决问题的方法。它工作正常,并且与libxml2兼容。
这是我的message.rng
文件:
$ cat message.rng
<element name="message" xmlns="http://relaxng.org/ns/structure/1.0">
<interleave>
<zeroOrMore>
<element name="from">
<text/>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="to">
<text/>
</element>
</zeroOrMore>
<zeroOrMore>
<element name="cc">
<text/>
</element>
</zeroOrMore>
<optional>
<element name="subject">
<text/>
</element>
</optional>
<optional>
<element name="body">
<text/>
</element>
</optional>
</interleave>
</element>
以下是我的3个XML示例(message-1.xml
,message-2.xml
和message-3.xml
)的结果:
$ xmllint --relaxng message.rng message-1.xml
<?xml version="1.0"?>
<message>
<from>me@domain.com</from>
<to>you@domain.com</to>
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
</message>
message-1.xml validates
$ xmllint --relaxng message.rng message-2.xml
<?xml version="1.0"?>
<message>
<subject>How are you?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<from>me@domain.com</from>
<to>you@domain.com</to>
<to>and-you@domain.com</to>
<cc>someone-else@domain.com</cc>
<cc>again-someone-else@domain.com</cc>
</message>
message-2.xml validates
$ xmllint --relaxng message.rng message-3.xml
<?xml version="1.0"?>
<message>
<from>me@domain.com</from>
<from>someone-else@domain.com</from>
<to>you@domain.com</to>
<subject>How are you?</subject>
<subject>How are you again?</subject>
<body>Hello. How are you? Thank you. Best regards.</body>
<body>Hello. How are you again? Thank you. Best regards.</body>
</message>
Relax-NG validity error : Extra element subject in interleave
message-3.xml:7: element subject: Relax-NG validity error : Element message failed to validate content
message-3.xml fails to validate
答案 0 :(得分:0)
在XSD 1.0中,如果要允许元素以任何顺序出现,那么控制每个元素出现频率的唯一方法是使用xs:all,这会将出现次数限制为零或一。所以你无法实现你的目标。
此限制在XSD 1.1中解除。