Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XML
|
XML General XML discussions.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XML section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old May 16th, 2007, 11:02 AM
Registered User
 
Join Date: May 2007
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default IS-A , not CONTAINS-A design possible?

I have the following design problem. Maybe somebody can help

Suppose there is this concept of a Leaf
that can be an array of one three varieties determined by a type
attribute called tid.
One type is a string of length 32,
   the other an integer, and the other a double.

This is what I have now (together with its validating schema)
note.xml
1 <?xml version="1.0"?>
2 <note
3 xmlns="//LHickey/D/gfx/xml/examples"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="//LHickey/D/gfx/xml/examples note.xsd">
6
7
8 <Leaf tid="A32" name="Clawsons">
9 <A32Leaf tid="A32" len="4">
10 <title>clawsons best </title>
11 <a32arrayelement xsi:nil="true" />
12 <a32arrayelement xsi:nil="true" />
13 <a32arrayelement>abcdef</a32arrayelement>
14 <a32arrayelement>
               01234567890123456789012345678912
            </a32arrayelement>
15 </A32Leaf>
16 </Leaf>
17
18 <Leaf tid="Int" name="Fred">
19 <ILeaf tid="Int" len="4">
20 <title> howdy fred </title>
21 <iarrayelement>1</iarrayelement>
22 <iarrayelement>2</iarrayelement>
23 <iarrayelement>3</iarrayelement>
24 <iarrayelement xsi:nil="true"/>
25 </ILeaf>
26 </Leaf>
27
28 <Leaf tid="Dbl" name="Wilma">
29 <DLeaf tid="Dbl" len="4">
30 <title> howdy wilma </title>
31 <darrayelement>1</darrayelement>
32 <darrayelement>2</darrayelement>
33 <darrayelement>3</darrayelement>
34 <darrayelement xsi:nil="true"/>
35 </DLeaf>
36 </Leaf>
37
38 <Leaf tid="Dbl" name="Thing"/>
39
40 </note>

This says that a Leaf is a container for one of three types (A32Leaf tid="A32")
or (ILeaf tid="Int"), or (DLeaf tid="Dbl").

I really want Leaf to BE one of one of the three types. Note in the note.xml above,
we have tid duplicated in the Leaf emement ,and in each of the contained elements.
Here is the schema for this thing
note.xsd
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <xs:schema
 3 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 4 targetNamespace="//LHickey/D/gfx/xml/examples"
 5 xmlns="//LHickey/D/gfx/xml/examples"
 6 elementFormDefault="qualified">
 7
 8 <xs:simpleType name="a32Def">
 9 <xs:restriction base="xs:string">
10 <xs:maxLength value="32"/>
11 </xs:restriction>
12 </xs:simpleType>
13
14
15 <xs:complexType name="aleafset">
16 <xs:sequence>
17 <xs:element name="title" type= "xs:string" />
18 <xs:element name="a32arrayelement" type="a32Def"
                  minOccurs="0" maxOccurs="unbounded"
                  nillable="true" />
19 </xs:sequence>
20 <xs:attribute name="tid" type="xs:string"
                  use="required" fixed="A32"/>
21 <xs:attribute name="len" type="xs:integer"
             use="required" />
22 </xs:complexType>
23
24
25 <xs:simpleType name="intDefx">
26 <xs:restriction base="xs:integer">
27 </xs:restriction>
28 </xs:simpleType>
29
30 <xs:complexType name="ileafset">
31 <xs:sequence>
32 <xs:element name="title" type= "xs:string" />
33 <xs:element name="iarrayelement" type="intDefx"
               minOccurs="0" maxOccurs="unbounded"
               nillable="true" />
34 </xs:sequence>
35 <xs:attribute name="tid" type="xs:string"
               use="required" fixed="Int"/>
36 <xs:attribute name="len" type="xs:integer"
                use="required" />
37 </xs:complexType>
38
39 <xs:simpleType name="dblDefx">
40 <xs:restriction base="xs:double">
41 </xs:restriction>
42 </xs:simpleType>
43
44 <xs:complexType name="dleafset">
45 <xs:sequence>
46 <xs:element name="title" type= "xs:string" />
47 <xs:element name="darrayelement" type="dblDefx"
                  minOccurs="0" maxOccurs="unbounded"
                  nillable="true" />
48 </xs:sequence>
49 <xs:attribute name="tid" type="xs:string"
               use="required" fixed="Dbl" />
50 <xs:attribute name="len" type="xs:integer"
             use="required" />
51 </xs:complexType>
52
53
54 <xs:complexType name="leafdef" >
55 <xs:choice minOccurs="0">
56 <xs:element name="A32Leaf" type="aleafset"/>
57 <xs:element name="ILeaf" type="ileafset"/>
58 <xs:element name="DLeaf" type="dleafset"/>
59 </xs:choice>
60 <xs:attribute name="tid" use="required" >
61 <xs:simpleType>
62 <xs:restriction base="xs:string">
63 <xs:pattern value="A32|Int|Dbl"/>
64 </xs:restriction>
65 </xs:simpleType>
66 </xs:attribute>
67 <xs:attribute name="name" type="xs:token"
             use="required" />
68
69 </xs:complexType>
70
71 <xs:element name="note" >
72 <xs:complexType>
73 <xs:sequence>
74 <xs:element name="Leaf" type="leafdef"
                  minOccurs="0" maxOccurs="unbounded"/>
75 </xs:sequence>
76 </xs:complexType>
77 </xs:element>
78
79 </xs:schema>

Not only am I saddled with the creation of this container element Leaf,
but I can't even find a way to make the schema check that
   Leaf.tid=either A32Leaf.tid or ILeaf.tid or DLeaf.tid.

What I really want is to declare Leaf IS.A A32Leaf or ILeaf or DLeaf.tid,
not Leaf CONTAINS.A.SINGLE.INSTANCE.OF (A32Leaf|ILeaf|DLeaf) like I have now.
---

This is what I want is an xml schema that works like this,
where the tid determines the legal content to follow.

<Leaf tid="A32" name="Clawsons" ,len="4">
   <title>clawsons best </title>
   <a32arrayelement xsi:nil="true" />
   <a32arrayelement xsi:nil="true" />
   <a32arrayelement>abcdef</a32arrayelement>
   <a32arrayelement>
      01234567890123456789012345678912
   </a32arrayelement>
</Leaf>

<Leaf tid="Int" name="Fred" ,len="4">
   <title> howdy fred </title>
   <iarrayelement>1</iarrayelement>
   <iarrayelement>2</iarrayelement>
   <iarrayelement>3</iarrayelement>
   <iarrayelement xsi:nil="true"/>
</Leaf>

<Leaf tid="Dbl" name="Wilma" , len="4">
   <title> howdy wilma </title>
   <darrayelement>1</darrayelement>
   <darrayelement>2</darrayelement>
   <darrayelement>3</darrayelement>
   <darrayelement xsi:nil="true"/>
</Leaf>


This is what I want as a C program
nbf.c
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 struct LeafDef
  5 {
  6 char Name[32]; * no spaces- a compact identifier for leaf*/
  7 char Title[128];/*display name for the leaf. max len=128*/
  8 int Len; /* length of the array U */
  9 enum TidDef {A32=0,Int=1,Dbl=2} tid;
 10 union LeafTypeUnion /* array is of this type */
 11 {
 12 char (*a32arrayelement)[32+1]; /* use with tid=A32 */
 13 int *iarrayelement; /* use with tid=Int */
 14 double *darrayelement; /* use with tid=Dbl */
 15 } *U; /* malloc Len of these pointers */
 16 };
 17 /*The U(pointed to) objects pointers too so they are nillable*/
 18 main(int argc,char **argv)
 19 {
 20 struct LeafDef *L = calloc(1,sizeof(struct LeafDef));
 21 L->tid = A32;
 22 strcpy(L->Name, "Clawsons");
 23 strcpy(L->Title, "clawsons best");
 24 L->Len = 4;
 25 L->U = calloc(L->Len,sizeof(union LeafTypeUnion));
 26 L->U[0].a32arrayelement = (char (*)[32+1]) 0; /* nill */
 27 L->U[1].a32arrayelement = (char (*)[32+1]) 0; /* nill */
 28 {
 29 L->U[2].a32arrayelement = calloc(1,sizeof (char [32+1]));
 30 strcpy((char *)L->U[2].a32arrayelement ,"abcdef");
 31 }
 32 {
 33 L->U[3].a32arrayelement = calloc(1,sizeof (char [32+1]));
 34 strcpy((char *)L->U[2].a32arrayelement,
             "01234567890123456789012345678912");
 35 }
 36 }
---------------------------------------------------------------
Is there some way I can read the xml into a C++ derivative of the above C prog
and use the xml and xsd schema to automatically load a Leaf struct? I undertand
this sort of thing is possible.


 
Old May 16th, 2007, 11:14 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>where the tid determines the legal content to follow.

That's a pretty succinct statement of requirements for the facility known as "conditional type assignment" which is being worked on for XML Schema 1.1. It can't be done in 1.0. The nearest you can get is to replace your use of tid with xsi:type. In XML Schema, there are only two ways to "select" the content model of an element: by the element name, and by xsi:type.

However, I can't see why you have the Leaf element as well as A32Leaf and friends. It's quite possible to define note as containing a sequence of elements each of which is either an A32Leaf, an ILeaf, or a DLeaf.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 16th, 2007, 02:10 PM
Registered User
 
Join Date: May 2007
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Forgive me for geing green at this: I might be dense but

now: leafdef CONTAIN a choice of three things, each of which is an array of uniform type.

I dont want leafdef to be an array of a choice of three things.i.e.
(an array of things of the different 3 types)

I want leafdef to BE a choice of being either 1) an array of a32 things
2) an array of Int things or 3) and array of Dbl things.
Not to CONTAIN a choice.

In other words, this newcommer needs a hint for
how to write the schema for this note.xml
----------------------------------------------
<note>
<Leaf tid="A32" name="Clawsons" ,len="4">
   <title>clawsons best </title>
   <a32arrayelement xsi:nil="true" />
   <a32arrayelement xsi:nil="true" />
   <a32arrayelement>abcdef</a32arrayelement>
   <a32arrayelement>
      01234567890123456789012345678912
   </a32arrayelement>
</Leaf>

<Leaf tid="Int" name="Fred" ,len="4">
   <title> howdy fred </title>
   <iarrayelement>1</iarrayelement>
   <iarrayelement>2</iarrayelement>
   <iarrayelement>3</iarrayelement>
   <iarrayelement xsi:nil="true"/>
</Leaf>

<Leaf tid="Dbl" name="Wilma" , len="4">
   <title> howdy wilma </title>
   <darrayelement>1</darrayelement>
   <darrayelement>2</darrayelement>
   <darrayelement>3</darrayelement>
   <darrayelement xsi:nil="true"/>
</Leaf>
</note>

 
Old May 16th, 2007, 03:34 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

As I said, you can't make the contents of the leaf element depend on the value of tid. But you can have three different kinds of element, aleaf, ileaf and dleaf, and you can define the content of note to be a sequence of X where X is a choice of aleaf, ileaf, and dleaf, that is a sequence whose members are aleaf, ileaf, and dleaf elements in any order.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Design issue DeborahP Access 1 March 24th, 2007 08:57 AM
Design patterns for web design ceadge HTML Code Clinic 0 June 19th, 2006 11:26 AM
How to design the following? gilgalbiblewheel HTML Code Clinic 0 January 14th, 2005 02:02 PM
Design help [email protected] Access 2 August 16th, 2004 10:01 AM
Java Design issue with UML and Design Patterns the_logical_way Apache Tomcat 0 May 31st, 2004 04:02 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.