<!--
  This DTD attempts to comprehensively test all of the various types of
  JSON annotations
-->

<!--~~ !dtd
~~json
  <json type='sample5' version='0.3'>
    <config lcnames='true' />
  </json>
~~-->

<!--~~ <Root>
~~tags root
~~json <object/>
~~-->
<!ELEMENT Root ( 
  test00, test01, test02, test03, test04, test05, test06, 
  test07, test08, test09,
  test15, test16, test17, test18, test19, test20, test21,
  test26, test27, array-container,
  test35, test36, test37, test38, test39,
  test45, test46, test47, test48, test49, test50, test51,
  test55, test56, test57, test58, test59, test60  )>

<!--==========================================-->
<!-- test objects  -->

<!--~~ <test00>
Test without annotation, this will be turned into an object.
~~-->
<!ELEMENT test00 ( test00-c1, test00-c2 )>
<!ELEMENT test00-c1 (#PCDATA)>
<!ELEMENT test00-c2 (#PCDATA)>
<!ATTLIST test00 test00-a1 CDATA #IMPLIED
                 test00-a2 CDATA #IMPLIED>


<!--~~ <test01>
Test the o annotation by itself.
~~json <object/>
~~-->
<!ELEMENT test01 ( test01-c1, test01-c2 )>
<!ELEMENT test01-c1 (#PCDATA)>
<!ELEMENT test01-c2 (#PCDATA)>
<!ATTLIST test01 test01-a1 CDATA #IMPLIED
                 test01-a2 CDATA #IMPLIED>

<!--~~ <test02>
Test the o annotation with a key.
~~json <object key='test02-key'/>
~~-->
<!ELEMENT test02 ( test02-c1, test02-c2 )>
<!ELEMENT test02-c1 (#PCDATA)>
<!ELEMENT test02-c2 (#PCDATA)>
<!ATTLIST test02 test02-a1 CDATA #IMPLIED
                 test02-a2 CDATA #IMPLIED>

<!--~~ <test03>
Test the o annotation with a name with an XPath expression.
~~json <object name='@test03-a1'/>
~~-->
<!ELEMENT test03 ( test03-c1, test03-c2 )>
<!ELEMENT test03-c1 (#PCDATA)>
<!ELEMENT test03-c2 (#PCDATA)>
<!ATTLIST test03 test03-a1 CDATA #IMPLIED
                 test03-a2 CDATA #IMPLIED>

<!--~~ <test04>
Test the o annotation with a select.
~~json <object select='@*|test04-c2'/>
~~-->
<!ELEMENT test04 ( test04-c1, test04-c2 )>
<!ELEMENT test04-c1 (#PCDATA)>
<!ELEMENT test04-c2 (#PCDATA)>
<!ATTLIST test04 test04-a1 CDATA #IMPLIED
                 test04-a2 CDATA #IMPLIED>

<!--~~ <test05>
Test with a member child.
~~json 
  <object>
    <members/>
  </object>
~~-->
<!ELEMENT test05 ( test05-c1, test05-c2 )>
<!ELEMENT test05-c1 (#PCDATA)>
<!ELEMENT test05-c2 (#PCDATA)>
<!ATTLIST test05 test05-a1 CDATA #IMPLIED
                 test05-a2 CDATA #IMPLIED>

<!--~~ <test06>
Test a member child that has a @select.  This should be similar to test04.
~~json 
  <object>
    <members select='@*|test06-c2'/>
  </object>
~~-->
<!ELEMENT test06 ( test06-c1, test06-c2 )>
<!ELEMENT test06-c1 (#PCDATA)>
<!ELEMENT test06-c2 (#PCDATA)>
<!ATTLIST test06 test06-a1 CDATA #IMPLIED
                 test06-a2 CDATA #IMPLIED>

<!--~~ <test07>
Test lots of different string kids.
~~json 
  <object>
    <string key='a1' select='@test07-a1'/>
    <string name='@test07-a2' select='@test07-a2'/>
    <string key='3'>Here's a nice string.</string>
  </object>
~~-->
<!ELEMENT test07 ( test07-c1, test07-c2 )>
<!ELEMENT test07-c1 (#PCDATA)>
<!ELEMENT test07-c2 (#PCDATA)>
<!ATTLIST test07 test07-a1 CDATA #IMPLIED
                 test07-a2 CDATA #IMPLIED>

<!--~~ <test08>
Test an array kid with various grandkids.
~~json 
  <object>
    <array key='fleegle'>
      <string key='a1' select='@test08-a1'/>
      <string name='@test08-a2' select='@test08-a2'/>
      <string key='3'>Here's a nice string.</string>
    </array>
    <array key='drooper'>
      <boolean key='a4' select='@test08-a4'/>
      <boolean name='@test08-a5' select='@test08-a5'/>
      <boolean name='@test08-a6' select='@test08-a6'/>
      <boolean key='7'> false </boolean>
      <boolean key='8'> 0 </boolean>
      <boolean key='9'> true </boolean>
    </array>
    <array key='snorky'>
      <number select='@test08-a10'/>
      <number select='@test08-a11'/>
      <number select='@test08-a12'/>
      <number> 22</number>
      <number> 01  </number>
    </array>
  </object>
~~-->
<!ELEMENT test08 ( test08-c1, test08-c2 )>
<!ELEMENT test08-c1 (#PCDATA)>
<!ELEMENT test08-c2 (#PCDATA)>
<!ATTLIST test08 test08-a1 CDATA #IMPLIED
                 test08-a2 CDATA #IMPLIED
                 test08-a4 CDATA #IMPLIED
                 test08-a5 CDATA #IMPLIED
                 test08-a6 CDATA #IMPLIED
                 test08-a10 CDATA #IMPLIED
                 test08-a11 CDATA #IMPLIED
                 test08-a12 CDATA #IMPLIED>

<!--~~ <test09>
Test an object with text kids.
~~json <object/>
~~-->
<!ELEMENT test09 (#PCDATA | test09-c1 | test09-c2)*>
<!ELEMENT test09-c1 (#PCDATA)>
<!ELEMENT test09-c2 (#PCDATA)>
<!ATTLIST test09 test09-a1 CDATA #IMPLIED
                 test09-a2 CDATA #IMPLIED>



<!--==========================================-->
<!-- test arrays  -->

<!--~~ <test15>
Without annotation, this should be turned into an array.
~~-->
<!ELEMENT test15 ( test15-c1+ ) >
<!ELEMENT test15-c1 (#PCDATA)>

<!--~~ <test16>
Test the a annotation by itself.  Note that this will drop
the attributes, since by default, the selector for array is "*".
~~json <array/>
~~-->
<!ELEMENT test16 ( test16-c1, test16-c2 )>
<!ELEMENT test16-c1 (#PCDATA)>
<!ELEMENT test16-c2 (#PCDATA)>
<!ATTLIST test16 test16-a1 CDATA #IMPLIED
                 test16-a2 CDATA #IMPLIED>

<!--~~ <test17>
Test the a annotation with a key.
~~json <array key='test17-key'/>
~~-->
<!ELEMENT test17 ( test17-c1, test17-c2 )>
<!ELEMENT test17-c1 (#PCDATA)>
<!ELEMENT test17-c2 (#PCDATA)>
<!ATTLIST test17 test17-a1 CDATA #IMPLIED
                 test17-a2 CDATA #IMPLIED>

<!--~~ <test18>
Test the a annotation with a name.
~~json <array name='@test18-a1'/>
~~-->
<!ELEMENT test18 ( test18-c1, test18-c2 )>
<!ELEMENT test18-c1 (#PCDATA)>
<!ELEMENT test18-c2 (#PCDATA)>
<!ATTLIST test18 test18-a1 CDATA #IMPLIED
                 test18-a2 CDATA #IMPLIED>

<!--~~ <test19>
Test the a annotation with a select.
~~json <array select='@*|test19-c2'/>
~~-->
<!ELEMENT test19 ( test19-c1, test19-c2 )>
<!ELEMENT test19-c1 (#PCDATA)>
<!ELEMENT test19-c2 (#PCDATA)>
<!ATTLIST test19 test19-a1 CDATA #IMPLIED
                 test19-a2 CDATA #IMPLIED>

<!--~~ <test20>
Test an array with a member child.  This "members" will only
pull out the child elements, and discard the attributes.
~~json 
  <array>
    <members/>
  </array>
~~-->
<!ELEMENT test20 ( test20-c1, test20-c2 )>
<!ELEMENT test20-c1 (#PCDATA)>
<!ELEMENT test20-c2 (#PCDATA)>
<!ATTLIST test20 test20-a1 CDATA #IMPLIED
                 test20-a2 CDATA #IMPLIED>

<!--~~ <test21>
Test an array with some mixed-up kids
~~json 
  <array>
    <members select='@*|test21-c2'/>
    <string select='@test21-a2'/>
    <string>Here's a nice string.</string>
    <boolean> 0 </boolean>
    <boolean select='@test21-a3'/>
    <number>  3.14159</number>
    <number select='@test21-a4'/>
  </array>
~~-->
<!ELEMENT test21 ( test21-c1, test21-c2 )>
<!ELEMENT test21-c1 (#PCDATA)>
<!ELEMENT test21-c2 (#PCDATA)>
<!ATTLIST test21 test21-a1 CDATA #IMPLIED
                 test21-a2 CDATA #IMPLIED
                 test21-a3 CDATA #IMPLIED
                 test21-a4 CDATA #IMPLIED>


<!--==========================================-->
<!-- test members -->

<!--~~ <test26>
Test members by itself.  This should cause this element to be "flattened".
All the attributes and child elements will be inserted as key:value pairs
right in the parent object.  Because the context of this, when it is 
resolved at runtime, is "o", the default selector will be "@*|*" (all
attributes and child elements).
~~json <members/>
~~-->
<!ELEMENT test26 ( test26-c1, test26-c2 )>
<!ELEMENT test26-c1 (#PCDATA)>
<!ELEMENT test26-c2 (#PCDATA)>
<!ATTLIST test26 test26-a1 CDATA #IMPLIED
                 test26-a2 CDATA #IMPLIED>

<!--~~ <test27>
Test members with a @select.
~~json <members select='@test27-a1|test27-c2'/>
~~-->
<!ELEMENT test27 ( test27-c1, test27-c2 )>
<!ELEMENT test27-c1 (#PCDATA)>
<!ELEMENT test27-c2 (#PCDATA)>
<!ATTLIST test27 test27-a1 CDATA #IMPLIED
                 test27-a2 CDATA #IMPLIED>

<!--~~ <test28>
Test members as the root annotation, without a select,
inside an array.  First we'll need to declare a container element
to provide the array.  The context of this, resolved at runtime, will
be "a", so the default selector will be "*" (only child elements;
attributes will be dropped.)
~~json <members/>
~~-->
<!ELEMENT array-container (test28)+ >
<!ELEMENT test28 ( test28-c1, test28-c2 )>
<!ELEMENT test28-c1 (#PCDATA)>
<!ELEMENT test28-c2 (#PCDATA)>
<!ATTLIST test28 test28-a1 CDATA #IMPLIED
                 test28-a2 CDATA #IMPLIED>

<!--==========================================-->
<!-- test json as the root annotation -->

<!--~~ <test35>
Test json without any attributes.  This will have no effect.
~~json <json/>
~~-->
<!ELEMENT test35 ( test35-c1, test35-c2 )>
<!ELEMENT test35-c1 (#PCDATA)>
<!ELEMENT test35-c2 (#PCDATA)>
<!ATTLIST test35 test35-a1 CDATA #IMPLIED
                 test35-a2 CDATA #IMPLIED>

<!--~~ <test36>
Test json with a key.  
~~json <json key='TEST36'/>
~~-->
<!ELEMENT test36 ( test36-c1, test36-c2 )>
<!ELEMENT test36-c1 (#PCDATA)>
<!ELEMENT test36-c2 (#PCDATA)>
<!ATTLIST test36 test36-a1 CDATA #IMPLIED
                 test36-a2 CDATA #IMPLIED>

<!--~~ <test37>
Test json with a name.  
~~json <json name='test37-c2'/>
~~-->
<!ELEMENT test37 ( test37-c1, test37-c2 )>
<!ELEMENT test37-c1 (#PCDATA)>
<!ELEMENT test37-c2 (#PCDATA)>
<!ATTLIST test37 test37-a1 CDATA #IMPLIED
                 test37-a2 CDATA #IMPLIED>

<!--~~ <test38>
Test json with a select.  
~~json <json select='*'/>
~~-->
<!ELEMENT test38 ( test38-c1, test38-c2 )>
<!ELEMENT test38-c1 (#PCDATA)>
<!ELEMENT test38-c2 (#PCDATA)>
<!ATTLIST test38 test38-a1 CDATA #IMPLIED
                 test38-a2 CDATA #IMPLIED>

<!--~~ <test39>
Test json with a bunch of stuff.  
~~json 
  <json name='@test39-a1'>
    <object key='fleegle'>
      <string name='@test39-a2'>This is the way the world ends ...</string>
    </object>
    <array key='bingo'>
      <string>... not with a bang but a whimper.</string>
    </array>
    <members select='*'/>
  </json>
~~-->
<!ELEMENT test39 ( test39-c1, test39-c2 )>
<!ELEMENT test39-c1 (#PCDATA)>
<!ELEMENT test39-c2 (#PCDATA)>
<!ATTLIST test39 test39-a1 CDATA #IMPLIED
                 test39-a2 CDATA #IMPLIED>

<!--==========================================-->
<!-- test elements with text children -->

<!--~~ <test45>
Here's an element with mixed content.  (Hypothetical) business rules specify
that there will be at most one non-whitespace text node.  In the object, the
text node will have the key "value".
Note that it is hard to fit true mixed content into an object.  It is best handled
either in an array (see the next test), or by using custom templates.
~~json 
  <object select='@*|node()'/>
~~-->
<!ELEMENT test45 ( #PCDATA | test45-c1 | test45-c2 )*>
<!ELEMENT test45-c1 (#PCDATA)>
<!ELEMENT test45-c2 (#PCDATA)>
<!ATTLIST test45 test45-a1 CDATA #IMPLIED
                 test45-a2 CDATA #IMPLIED>

<!--~~ <test46>
Here's an element with mixed content, put into an array.
~~json 
  <array select='@*|node()'/>
~~-->
<!ELEMENT test46 ( #PCDATA | test46-c1 | test46-c2 )*>
<!ELEMENT test46-c1 (#PCDATA)>
<!ELEMENT test46-c2 (#PCDATA)>
<!ATTLIST test46 test46-a1 CDATA #IMPLIED
                 test46-a2 CDATA #IMPLIED>

<!--~~ <test47>
An element with text-only content and no attributes.  This will just
be turned into a string.
~~-->
<!ELEMENT test47 (#PCDATA)>

<!--~~ <test48>
An element with text-only content and attributes.
~~-->
<!ELEMENT test48 (#PCDATA)>
<!ATTLIST test48 test48-a1 CDATA #IMPLIED
                 test48-a2 CDATA #IMPLIED>

<!--~~ <test49>
An element with text-only content and attributes, stuffed into an array.
Since it's an array, by default, attributes are dropped.
~~json <array/>
~~-->
<!ELEMENT test49 (#PCDATA)>
<!ATTLIST test49 test49-a1 CDATA #IMPLIED
                 test49-a2 CDATA #IMPLIED>

<!--~~ <test50>
The same thing but with a select attribute, that let's us include attributes.
~~json <array select='@*|node()'/>
~~-->
<!ELEMENT test50 (#PCDATA)>
<!ATTLIST test50 test50-a1 CDATA #IMPLIED
                 test50-a2 CDATA #IMPLIED>

<!--~~ <test51>
Here's how to indicate that the text content is a number.
~~json 
  <object>
    <number key='value' select='text()'/>
    <members/>
  </object>
~~-->
<!ELEMENT test51 (#PCDATA)>
<!ATTLIST test51 test51-a1 CDATA #IMPLIED
                 test51-a2 CDATA #IMPLIED>


<!--==========================================-->
<!-- test elements with simple types -->

<!--~~ <test55>
Same as test47 above, an element with text-only content and no attributes.  This will just
be turned into a string.
~~-->
<!ELEMENT test55 (#PCDATA)>

<!--~~ <test56>
Specify that it is a number, and specify a key.
~~json <number key='TEST56'/>
~~-->
<!ELEMENT test56 (#PCDATA)>

<!--~~ <test57>
Specify that it is a boolean, and specify a name that comes from an attribute.
~~json <boolean name='@test57-a1'/>
~~-->
<!ELEMENT test57 (#PCDATA)>
<!ATTLIST test57 test57-a1 CDATA #IMPLIED>

<!--~~ <test58>
Specify a string, but the value should come from one of the attributes.
~~json <string select='@test58-a1'/>
~~-->
<!ELEMENT test58 (#PCDATA)>
<!ATTLIST test58 test58-a1 CDATA #IMPLIED>

<!--~~ <test59>
Same thing but a number.
~~json <number select='@test59-a1'/>
~~-->
<!ELEMENT test59 (#PCDATA)>
<!ATTLIST test59 test59-a1 CDATA #IMPLIED>

<!--~~ <test60>
Same thing but a boolean.
~~json <boolean select='@test60-a1'/>
~~-->
<!ELEMENT test60 (#PCDATA)>
<!ATTLIST test60 test60-a1 CDATA #IMPLIED>





