问题
I'm struggling with my XML Schema and staring at the screen isn't helping. The XML I'm trying to create a schema for looks like this:
<root>
<command>FOO|BAR|BLOOP</command>
<parameters>
<param1>val</param1>
<param2>val</param2>
</parameters>
<root>
Depending on whether the command value = FOO, BAR or BLOOP a different set of parameters needs to be in the parameters-tag and it may be empty. The set of parameters that needs to appear for a certain command is defined and some command-names have the same set of parameters.
What I've though about doing is to create a type for every command, so one for FOO, one for BAR and one for BLOOP and in those types I could put the parameters they use.
However, when I do something like:
<xs:element name="root">
<xs:complexType>
<xs:element name="myCommand" type="myCommandType"/>
</xs:complexType>
</xs:element>
This creates a special element with a name for every command-type when in fact I just want the part between the root elements to be filled by whatever that command needs.
Any clue about the best way to go about this?
Would it be better to create a schema for every command or can I put them all in the same schema?
回答1:
First of all, you can't change the type of one tag (the <parameters>
tag) depending on the content of another (the <command>
tag), in general. There might be ugly and complicated ways to do it, but I would recommend a simple solution.
If you can, you should restructure your XML to something like this:
<root>
<foo-command>
<param1>val</param1>
<param2>val</param2>
<param3>val</param3>
</foo-command>
</root>
This is easy to do with Schema: define the content of <root>
to be a choice of your commands and create a complex type for each of them containing the parameter definitions.
Here's what this would look like:
<element name="root">
<complexType>
<choice>
<element name="foo-command" type="tns:foo-command-type"/>
<element name="bar-command" type="tns:bar-command-type"/>
...
</choice>
</complexType>
</element>
<complexType name="foo-command-type">
<sequence>
<element name="param1" type="boolean"/>
<element name="param2" type="int"/>
...
</sequence>
</complexType>
<complexType name="bar-command-type">
...
</complexType>
...
回答2:
The problem often goes under the name "co-occurrence constraints" and it's a well-known limitation of XSD 1.0 that there's no easy solution.
In XSD 1.1 there's a new feature called "conditional type assignment" that does exactly what you want. XSD 1.1 is currently implemented in Xerces and Saxon.
来源:https://stackoverflow.com/questions/12956369/how-to-create-an-xsd-choice-without-an-element-name