Forum Moderators: open

Message Too Old, No Replies

XSD, defining a vector type for attributes

<base position="187.743927, 68.104309, 225.431259">

         

eSite

11:34 pm on May 6, 2007 (gmt 0)



Hi,

I have several XML attributes that are vectors of those forms :

0.000,-100.000,15.00
0.000000, 1.000000, 1.00000
1000.000000, 150.000000, -10.00000

Example :
<base position="187.743927, 68.104309, 225.431259">

Eventually I could remove the commas :
0.000000 1.000000 1.00000

Note : keeping the 3 decimals in a single attribute makes things much simpler for my parser.

I've looked at [w3schools.com...] and [w3.org...] but I can't figure out what the restriction might be, I wonder if it's even possible to define a vector type for an attribute.

cmarshall

11:39 pm on May 6, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, if you defined it as xs:string, then you can have whatever you want. I'm not expert enough to know whether or not you can expect a schema to parse the contents a la RegEx. I would be surprised if it could, as that needs some serious horsepower.

If you are doing 3D stuff, you might want to look at X3D [web3d.org] (The technology formerly known as VRML).

cmarshall

1:39 am on May 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Actually, restrictions [w3schools.com] might give you what you want.

Let me mess around a bit with <oXygen/>, and see what I come up with...

cmarshall

2:01 am on May 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yeah, this looks like it'll work.

Here was my test (Coordinates.xsd):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:coordinate_test" elementFormDefault="qualified">
<xs:element name="container">
<xs:complexType>
<xs:sequence>
<xs:element name="coordinate">
<xs:complexType>
<xs:attribute name="coords" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="-?[\d]\.?[\d]{0,6},-?[\d]\.?[\d]{0,6},-?[\d]\.?[\d]{0,6}"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

The commas can be easily replaced by spaces.

Here's the example provided by <oXygen/> (with some tweaks by Moi):

<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="urn:coordinate_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:coordinate_test Coordinates.xsd">
<coordinate coords="0,-1.0,2.300405"/>
</container>

Seriously, if you don't already have it, get <oXygen/> or XMLSpy. I spent about fifteen minutes figuring this out. It would have taken a good deal longer for me to do it without <oXygen/>.

cmarshall

2:49 am on May 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a version that gets your example through the goalposts:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:coordinate_test" elementFormDefault="qualified">
<xs:element name="container">
<xs:complexType>
<xs:sequence>
<xs:element name="base">
<xs:complexType>
<xs:attribute name="position" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="-?[\d]\.?[\d]{0,6},-?[\d]\.?[\d]{0,6},-?[\d]\.?[\d]{0,6}"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="urn:coordinate_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:coordinate_test Coordinates.xsd">
<base position="0,-1.0,2.300405"/>
</container>

cmarshall

10:18 am on May 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<xs:pattern value="-?[\d]\.?[\d]{0,6},-?[\d]\.?[\d]{0,6},-?[\d]\.?[\d]{0,6}"/>

Actually, not quite. Here's a tweak:

<xs:pattern value="-?[\d]{1,3}(\.[\d]{1,6})?,-?[\d]{1,3}(\.[\d]{1,6})?,-?[\d]{1,3}(\.[\d]{1,6})?"/>

This prevents things like "1." or ".23".

Remember that this is a string match only. It does not test the validity of the numbers.

eSite

10:47 am on May 7, 2007 (gmt 0)



wow, thanks for your time, can you just explain what the syntax means?

cmarshall

11:02 am on May 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That's what is known as a regular expression [regular-expressions.info] (AKA "@#!#%! Regex!).

RegExes are not so simple to program, but, very, very powerful. They form the heart of the Perl programming language [perl.org], and are used, in one form or another, by almost every language out there.

It is well worth it to learn RegEx. It is pretty difficult to become an expert, but you don't need to become one to make good use of them.

Another thing that you can do is to make the coordinate type re-usable, by declaring a named simpleType in the global scope (this is how the schema schema declares things like xs:string and xs:integer).

It was my pleasure. I learned something myself. Restrictions are very useful.

cmarshall

11:55 am on May 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's a version that declares a generic type, and that also allows you to address a European audience (allows commas or decimal), and it uses whitespace as separators.

Remember that WebmasterWorld substitutes a "¦" character for a pipe character.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cr="urn:coordinate_test" targetNamespace="urn:coordinate_test" elementFormDefault="qualified">
<xs:simpleType name="coords3D">
<xs:restriction base="xs:string">
<xs:pattern value="-?[\d]{1,3}([\.¦,][\d]{1,6})?\s+-?[\d]{1,3}([\.¦,][\d]{1,6})?\s+-?[\d]{1,3}([\.¦,][\d]{1,6})?"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="container">
<xs:complexType>
<xs:sequence>
<xs:element name="base">
<xs:complexType>
<xs:attribute name="position" use="required" type="cr:coords3D"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Here's an example XML file:

<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="urn:coordinate_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:coordinate_test Coordinates.xsd">
<base position="0 -1,0 2.300405"/>
</container>