By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,130 Members | 2,228 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,130 IT Pros & Developers. It's quick & easy.

Can a schema be written to check for this?

P: n/a

Here is some highly imaginative XML I've constructed to highlight what
it is I'm trying to achieve. (Seems easier with an example).

<foobars>
<foo>
<bar x="dog" colour="brown"/>
<bar x="cat" colour="grey"/>
<bar x="fish" colour="gold"/>
</foo>
<foo>
<bar x="dog" colour="black"/>
<bar x="cat" colour="white"/>
<bar x="fish" colour="blue"/>
</foo>
</foobars>

I want to ENFORCE that every <foo> contains three <bar> children and
that "dog", "cat", and "fish" appear each once. It's easy to to say
that <bar> must occur max=3 and min=3 but I cannot specify that "dog",
"cat", and "fish" appear since I cannot define <bar> more than once in
my schema. I get some "duplicate declaration within current scope" error.

Now if I re-formed my XML document thusly:

<foobars>
<foo>
<bar>
<dog>brown</dog>
<cat>grey</cat>
<fish>gold</fish>
</bar>
</foo>

<foo>
<bar>
<dog>brown</dog>
<cat>grey</cat>
<fish>gold</fish>
</bar>
</foo>

</foobars>
It's possible to do because there is only one <bar> and <dog>, <cat>,
and <fish> all have different names and I can check that each one occurs
once and only once.

The thing is if I change my XML I have to change my app, so at the
moment my preferred solution is to find a way of writing a schema that
works for example #1.

Can it be done?
Jun 15 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a


Mr Flibble wrote:
Here is some highly imaginative XML I've constructed to highlight what
it is I'm trying to achieve. (Seems easier with an example).

<foobars>
<foo>
<bar x="dog" colour="brown"/>
<bar x="cat" colour="grey"/>
<bar x="fish" colour="gold"/>
</foo>
<foo>
<bar x="dog" colour="black"/>
<bar x="cat" colour="white"/>
<bar x="fish" colour="blue"/>
</foo>
</foobars>

I want to ENFORCE that every <foo> contains three <bar> children and
that "dog", "cat", and "fish" appear each once.


XSD does not allow you to put such constraints on attribute values. As
you have recognized yourself the proper way is to make dog, cat, fish
element names of elements your document contains.
If you want to put a constraint on attribute values then you might want
to try Schematron, it is a schema language that allows you to specify
assertions with the help of XPath. Schematron is however not supported
directly by any Microsoft XML parser. With the help of an XSLT processor
Schematron schemas can be checked.

--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Jun 15 '06 #2

P: n/a
Yes, you can do this using uniqueness constraints. The following snippet
does what you need. You need to make sure your schema declares a target
namespace (I assumed its prefix is "tns").

<xs:simpleType name="animalType">
<xs:restriction base="xs:string">
<xs:enumeration value="dog"/>
<xs:enumeration value="cat"/>
<xs:enumeration value="fish"/>
</xs:restriction>
</xs:simpleType>

<xs:complexType name="barType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="x" type="animalType"/>
<xs:attribute name="colour" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

<xs:complexType name="fooType">
<xs:sequence minOccurs="3" maxOccurs="3">
<xs:element name="bar" type="barType"/>
</xs:sequence>
</xs:complexType>

<xs:element name="foobars">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="fooType" maxOccurs="unbounded">
<xs:unique name="uniqueAnimal">
<xs:selector xpath="./tns:bar"/>
<xs:field xpath="@x"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

--
Stan Kitsis
Program Manager, XML Technologies
Microsoft Corporation

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
"Mr Flibble" <mr********@flibbyly.wobbly.n.et> wrote in message
news:e6***********@custnews.inweb.co.uk...

Here is some highly imaginative XML I've constructed to highlight what
it is I'm trying to achieve. (Seems easier with an example).

<foobars>
<foo>
<bar x="dog" colour="brown"/>
<bar x="cat" colour="grey"/>
<bar x="fish" colour="gold"/>
</foo>
<foo>
<bar x="dog" colour="black"/>
<bar x="cat" colour="white"/>
<bar x="fish" colour="blue"/>
</foo>
</foobars>

I want to ENFORCE that every <foo> contains three <bar> children and
that "dog", "cat", and "fish" appear each once. It's easy to to say
that <bar> must occur max=3 and min=3 but I cannot specify that "dog",
"cat", and "fish" appear since I cannot define <bar> more than once in
my schema. I get some "duplicate declaration within current scope" error.

Now if I re-formed my XML document thusly:

<foobars>
<foo>
<bar>
<dog>brown</dog>
<cat>grey</cat>
<fish>gold</fish>
</bar>
</foo>

<foo>
<bar>
<dog>brown</dog>
<cat>grey</cat>
<fish>gold</fish>
</bar>
</foo>

</foobars>
It's possible to do because there is only one <bar> and <dog>, <cat>,
and <fish> all have different names and I can check that each one occurs
once and only once.

The thing is if I change my XML I have to change my app, so at the
moment my preferred solution is to find a way of writing a schema that
works for example #1.

Can it be done?

Jun 16 '06 #3

P: n/a
* Stan Kitsis [MSFT] wrote:
Yes, you can do this using uniqueness constraints.


Thank you , that worked a TREAT!
Jun 19 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.