Fatih
Fatih

Reputation: 37

How can I create a schema for XML with different types

How can i create a XSD(Schema) for my XML below. I have tried everything but i just cant get it to work, even w3schools doesn't have any examples of how to get around this issue. I am trying to restrict and verify all the fields and also it needs to be able to work when someone adds a new app catagory e.g. <appCategory type="Sports">

<?xml version="1.0" encoding="ISO8859-1" ?>
<?xml-stylesheet type="text/xsl" href="q2.xsl"?>

<app xmlns="http://www.w3schools.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com q3.xsd">
    <appCategory type="Productivity">
        <appItem fileName="Messages" version="0.2" price="34.99">Thunderbird</appItem>
        <appItem fileName="Contacts" version="2.0" price="3.00">Convenience Book</appItem>
        <appItem fileName="Calendar" version="1.0" price="45.00">ForgetMilk</appItem>
        <appItem fileName="Email" version="1.3" price="3.45">Email</appItem>
    </appCategory>
    <appCategory type="Games">
        <appItem fileName="BrickBreaker" version="7.1" price="14.99">Brick Breaker</appItem>
        <appItem fileName="WordMole" version="4.1" price="22.99">Word Mole</appItem>
        <appItem fileName="FistOfAwesome" version="4.1" price="3.99">Fist of Awesome</appItem>      
    </appCategory>
    <appCategory type="Social networking">
        <appItem fileName="BlackBerry Messenger" version="0.2" price="0.99">Blackberry Messenger</appItem>
        <appItem fileName="Twitter" version="1.1" price="24.99">Twitter</appItem>
        <appItem fileName="Facebook" version="0.5" price="44.99">Facebook</appItem>
        <appItem fileName="Grodog" version="0.5" price="1.99">Grodog</appItem>
        <appItem fileName="LinkedIn" version="2.1" price="3.59">LinkedIn</appItem>
        <appItem fileName="YouTube" version="5.5" price="1.59">YouTube</appItem>
    </appCategory>
</app>

Upvotes: 1

Views: 84

Answers (2)

kjhughes
kjhughes

Reputation: 111491

it needs to be able to work when someone adds a new app category

This is a key requirement. If the someone who has to add a new app category is a person or organization responsible for enforcing that app XML documents are structured such that apps strictly must be found only in authorized categories, then see Michael Kay's answer.

If, however, the owner of the XSD wishes merely to capture a dynamic categorization of apps, and not enforce which items must appear in which categories, your design will suffice and the following simple XSD that will meet your needs.

You might even combine the approaches into two tiers where the first tier captures ongoing construction of the categorization of apps and a second tier provides validation against the categorization, perhaps after review and approval. The second tier might even be derived automatically from the first if the first were augmented with additional meta data regarding element/attribute names.

XML/XSD Example Without Namespaces

Online validation proof can be found here.

XML

<?xml version="1.0" encoding="ISO8859-1" ?>
<?xml-stylesheet type="text/xsl" href="q2.xsl"?>
<app>
    <appCategory type="Productivity">
        <appItem fileName="Messages" version="0.2" price="34.99">Thunderbird</appItem>
        <appItem fileName="Contacts" version="2.0" price="3.00">Convenience Book</appItem>
        <appItem fileName="Calendar" version="1.0" price="45.00">ForgetMilk</appItem>
        <appItem fileName="Email" version="1.3" price="3.45">Email</appItem>
    </appCategory>
    <appCategory type="Games">
        <appItem fileName="BrickBreaker" version="7.1" price="14.99">Brick Breaker</appItem>
        <appItem fileName="WordMole" version="4.1" price="22.99">Word Mole</appItem>
        <appItem fileName="FistOfAwesome" version="4.1" price="3.99">Fist of Awesome</appItem>      
    </appCategory>
    <appCategory type="Social networking">
        <appItem fileName="BlackBerry Messenger" version="0.2" price="0.99">Blackberry Messenger</appItem>
        <appItem fileName="Twitter" version="1.1" price="24.99">Twitter</appItem>
        <appItem fileName="Facebook" version="0.5" price="44.99">Facebook</appItem>
        <appItem fileName="Grodog" version="0.5" price="1.99">Grodog</appItem>
        <appItem fileName="LinkedIn" version="2.1" price="3.59">LinkedIn</appItem>
        <appItem fileName="YouTube" version="5.5" price="1.59">YouTube</appItem>
    </appCategory>
</app>

XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="app">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="appCategory" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="appItem" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute name="fileName"/>
                      <xs:attribute name="version"/>
                      <xs:attribute name="price"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="type"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163262

This kind of document design isn't what XML schemas were designed to handle. XML was designed to be extensible, and you are using it as if it wasn't, adding your own extensibility layer on top. If your document looked like this:

<app  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com q3.xsd">
    <Productivity>
        <Messages version="0.2" price="34.99">Thunderbird</Messages>
        <Contacts version="2.0" price="3.00">Convenience Book</Contacts>
        <Calendar version="1.0" price="45.00">ForgetMilk</Calendar>
        <Email version="1.3" price="3.45">Email</Email>
    </Productivity>
    <Games>
        <BrickBreaker version="7.1" price="14.99">Brick Breaker</BrickBreaker>
        <WordMole version="4.1" price="22.99">Word Mole</WordMole>
        <FistOfAwesome"= version="4.1" price="3.99">Fist of Awesome</FirstOfAwesome>      
    </Games>

then you would stand a much better chance.

Incidentally, you shouldn't be defining your elements in a namespace that isn't yours.

Upvotes: 1

Related Questions