tags:

views:

24

answers:

2

I have an XML spec that looks like this:

<Root>
    <Directory Name="SomeName">
        <TextFile Name="ExampleDocument.txt>This is the content of my sample text file.</TextFile>
        <Directory Name="SubDirectory">
            <Speech Name="Example Canned Speech">
               ...
            </Speech>
        </Directory>
    </Directory>
</Root>

Note that Directory elements can contain other Directory elements. How can I represent that using W3C Schema?

+2  A: 

This should do it (you may want to restrict names further than to xs:string):

<?xml version="1.0" encoding="utf-8"?>
<!-- Remember to change namespace name with your own -->
<xs:schema
    targetNamespace="http://tempuri.org/XMLSchema1.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
  <xs:element name="Root" type="Container"/>

  <xs:element name="Directory" >
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="Container">
          <xs:attribute name="Name" type="xs:string" use="required"/>
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>

  <xs:element name="TextFile">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="Name" use="required"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="Container">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Directory"/>
        <xs:element ref="TextFile"/>
      </xs:choice>
  </xs:complexType>
</xs:schema>

Tested on:

<?xml version="1.0" encoding="utf-8" ?>
<Root xmlns="http://tempuri.org/XMLSchema1.xsd"&gt;
  <Directory Name="SomeName">
    <TextFile Name="ExampleDocument.txt">This is the content of my sample text file.</TextFile>
    <Directory Name="SubDirectory">
    </Directory>
    <TextFile Name="hej">

    </TextFile>
  </Directory>
  <TextFile Name="file.txt"/>
</Root>
lasseespeholt
+1 for the most complete answer. Thank you very much.
Billy ONeal
+1  A: 

You need to create a recursive <complexType> to represent your <Directory> type. The following is an example of this technique, given the elements you provided.

  <xs:complexType name="DirectoryType">
    <xs:sequence>
      <xs:element name="TextFile"/>
      <xs:element name="Speech"/>
      <xs:element name="Directory" type="DirectoryType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Directory" type="DirectoryType" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
Steve Guidi
Checkmarking this answer because it does the best to explain clearly exactly what I have to do in the general case.
Billy ONeal