DTDs for VRML Daniel Lipkin (DLIPKIN@us.oracle.com) 15 Dec 98 10:07:19 -0800
From: http://www.vrml.org/WorkingGroups/dbwork/hypermail/1998/0223.html.
Len, Well, I guess it's time to have the DTD for VRML discussion! I'm moving the discussion to the enterprise mailing list so we can have a more focused group, and since it is part of our charter. By coincidence, I just finished putting together a DTD for VRML as an exercise. I'm including it here for comparison. Attached to this message are four files: vrml.dtd - DTD for fully representing VRML97 content example.wrl - simple VRML97 document example.xml - the same content expressed in XML vrml.xsl - preliminary XSL style sheet for translating the XML back into utf8 VRML Notice that my approach is very different from Len's (posted currently at http://ariadne.iz.net/~jeffs/vrmLab/Documentation/vrmlDTD.html). Mine is capable of representing all of VRML (Len's is just a subset conforming to a theoretical geometric profile), but Len's is arguably more readable/hand editable than mine. I still think there is little to no value in representing VRML97 in XML. (This may not be as true for VRMLng; we'll have to see). Some of my conclusions from builing this DTD: - the XML is bigger, difficult to read, and a pain to edit by hand - using DOM directly on the XML requires several additional levels of indirection compared to the equivalent EAI calls - there is still significant parser work required above and beyond the XML parsing to ensure that the VRML content is valid. BTW, I'll be happy to post all relevant documents to the enterprise site if folks find it helpful. Regards, -Daniel >>Date: Mon, 14 Dec 1998 11:26:19 -0600 >>From: "Bullard, Claude L (Len)" <clbullar@ingr.com> >>Subject: RE: Flatland >> >>If anyone is interested in a VRML97 set of XML tags, >>I have a DTD which maps the geometry subset as >>drafted in the geometry profile. It is easy to complete >>the rest if anyone wants to see how VRML maps to >>an XML application. This lets the members look >>at issues of tagging styles (tradeoffs when mapping >>to XML syntax and grammatical semantics), the >>problems of verbose vs cryptic tagging, and if anyone >>likes, a parsable basis for experimenting with the >>DOM in a VRML application. >> >>I'll post it to any site that wants to put it up for >>folks to troll. >> >>Len Bullard >>Intergraph Public Safety >>clbullar@ingr.com ****************************************************************************** Daniel Lipkin Principal Technical Staff, Oracle Worlds Internet Products Division Oracle Corporation (650) 506-3603 dlipkin@us.oracle.com http://www.olab.com/vrml/vrml.html --=_ORCL_26532646_0_0 Content-Transfer-Encoding:7bit Content-Type:text/plain; name="vrml.dtd"; charset="us-ascii" Content-Disposition:attachment; filename="vrml.dtd" <!-- DTD for representing VRML97 documents. Created 12/1/98 by Daniel Lipkin Copyright (c) 1998 by Oracle Corporation. All Rights Reserved. This DTD is designed to fully represent the contents of a VRML97 document as simply as possible. It is not designed to ensure that the contents are a fully legal VRML97 document; a secondary processor is necessary to ensure that all fields are legal fields for the node that contains them, that number formats are correct, that only field and exposedField definitions have default values, etc. There is a generic node element that contains elements for the various field types. This allows PROTO instances to be treated the same as built-in nodes. There are several areas where this DTD could be modified to provide additional constraints on the correctness of the VRML code, at a cost of additional complexity. These include: - Distinguishing between interface declarations. Those in PROTOs can take a default value. Those in EXTERNPROTOs cannot. Those in Scripts can take both a default value and an IS mapping - Elements for each field type to ensure, for example, that an MFString only contains String elements - Distinguishing between eventIn/eventOut interface declarations and field declarations. --> <!ENTITY % nodeStatement "node | script | use"> <!ENTITY % protoStatement "proto | externproto"> <!-- The different field types - either an SF or MF value. I also separate out the sfnode/mfnode type for clarity. --> <!ENTITY % field "sffield | sfnode | mffield | mfnode"> <!-- Common attributes among all fields. --> <!ENTITY % field-attr "name CDATA #REQUIRED is CDATA #IMPLIED"> <!-- Common attributes among all interface definitions. --> <!ENTITY % field-def "type (eventIn | eventOut | field | exposedField) #REQUIRED fieldType (SFBool | SFColor | MFColor | SFFloat | MFFloat| SFImage | SFInt32 | MFInt32 | SFNode | MFNode | SFRotation | MFRotation | SFString | MFString | SFTime | MFTime | SFVec2f | MFVec2f| SFVec3f | MFVec3f) #REQUIRED name CDATA #REQUIRED"> <!-- Vrml is the root node of the document. It contains zero or more proto definitions, nodes, and routes. --> <!ELEMENT vrml ( %protoStatement; | %nodeStatement; | route )*> <!ELEMENT node (%field;)*> <!-- A node has a required type (ie "Box") and an optional DEF name. We treat the DEF as an ID attribute. --> <!ATTLIST node type CDATA #REQUIRED def ID #IMPLIED> <!-- A use element simply references another node. --> <!ELEMENT use EMPTY> <!ATTLIST use node IDREF #REQUIRED> <!-- A Script is like a node except it also contains zero or more script interfaces. --> <!ELEMENT script (interface*, (%field;)*)> <!ATTLIST script def ID #IMPLIED> <!-- A interface is a field definition with an optional default value and an optional IS mapping. --> <!ELEMENT interface (fieldDefinition)*> <!ELEMENT fieldDefinition (field)?> <!ATTLIST fieldDefinition %field-def; is CDATA #IMPLIED> <!-- An EXTERNPROTO contains an interface followed by a url value. Use a String element to store the URL (we can't directly use #PCDATA because this would violate XML's rules for mixed content. --> <!ELEMENT externproto ( (interface)*, string)> <!ATTLIST externproto nodeType CDATA #REQUIRED> <!-- A PROTO contains an interface followed by a vrml scene. --> <!ELEMENT proto ( (interface)*, vrml)> <!ATTLIST proto nodeType CDATA #REQUIRED> <!-- An SF field contains a single field value. An MF field contains multiple field values. --> <!ELEMENT sffield (bool | color | float | image | int32 | rotation | string | time | vec2f | vec3f) > <!ATTLIST sffield %field-attr;> <!ELEMENT mffield ((color)* | (float)* | (int32)* | (rotation)* | (string)* | (time)* | (vec2f)* | (vec3f)*) > <!ATTLIST mffield %field-attr;> <!ELEMENT sfnode (%nodeStatement;)> <!ATTLIST sfnode %field-attr;> <!ELEMENT mfnode (%nodeStatement;)*> <!ATTLIST mfnode %field-attr;> <!-- The various elements representing field types are fairly self-explainatory. --> <!ELEMENT bool EMPTY> <!ATTLIST bool value (TRUE | FALSE) #REQUIRED> <!ELEMENT color EMPTY> <!ATTLIST color r CDATA #REQUIRED g CDATA #REQUIRED b CDATA #REQUIRED> <!ELEMENT float EMPTY> <!ATTLIST float value CDATA #REQUIRED> <!ELEMENT image (#PCDATA)> <!ATTLIST image width CDATA #REQUIRED height CDATA #REQUIRED count CDATA #REQUIRED> <!ELEMENT int32 EMPTY> <!ATTLIST int32 value CDATA #REQUIRED> <!ELEMENT rotation EMPTY> <!ATTLIST rotation axisX CDATA #REQUIRED axisY CDATA #REQUIRED axisZ CDATA #REQUIRED angle CDATA #REQUIRED> <!ELEMENT string (#PCDATA)> <!ELEMENT time EMPTY> <!ATTLIST time value CDATA #REQUIRED> <!ELEMENT vec2f EMPTY> <!ATTLIST vec2f x CDATA #REQUIRED y CDATA #REQUIRED> <!ELEMENT vec3f EMPTY> <!ATTLIST vec3f x CDATA #REQUIRED y CDATA #REQUIRED z CDATA #REQUIRED> <!ELEMENT route EMPTY> <!ATTLIST route fromnode IDREF #REQUIRED fromevent CDATA #REQUIRED tonode IDREF #REQUIRED toevent CDATA #REQUIRED> --=_ORCL_26532646_0_0 Content-Transfer-Encoding:7bit Content-Type:text/plain; name="example.wrl"; charset="us-ascii" Content-Disposition:attachment; filename="example.wrl" #VRML V2.0 utf8 PROTO DownArrow [ eventOut SFBool clicked ] { Transform { scale .5 .5 .5 rotation 1 0 0 2.5 children [ Shape { appearance Appearance { material Material { diffuseColor .5 .5 .5 } } geometry Cone {} } DEF dats TouchSensor {} DEF das Script { eventIn SFBool inEvent eventOut SFBool outEvent IS clicked url "javascript: function inEvent(value, ts) { if (!(value)) outEvent = true; }" } ] } ROUTE dats.isActive TO das.inEvent } Background { groundAngle 1 groundColor 0 0 .4 skyColor 0 0 .4 skyAngle 1 } NavigationInfo { type "FLY" } DEF Slide1 Viewpoint { position 6 -3 20 description "Slide 1" } DEF Slide2 Viewpoint { position 5 -24 70 description "Slide 2" } Transform { translation 10 -6 0 children [ DEF Next1 DownArrow {} ] } ROUTE Next1.clicked TO Slide2.set_bind --=_ORCL_26532646_0_0 Content-Transfer-Encoding:7bit Content-Type:text/plain; name="example.xml"; charset="us-ascii" Content-Disposition:attachment; filename="example.xml" <?xml version="1.0"?> <!DOCTYPE vrml SYSTEM "vrml.dtd"> <vrml> <proto nodeType="DownArrow"> <interface> <fieldDefinition type="eventOut" fieldType="SFBool" name="clicked"> </fieldDefinition> </interface> <vrml> <node type="Transform"> <sffield name="scale"> <vec3f x=".5" y=".5" z=".5"/> </sffield> <sffield name="rotation"> <rotation axisX="1" axisY="0" axisZ="0" angle="2.5"/> </sffield> <mfnode name="children"> <node type="Shape"> <sfnode name="appearance"> <node type="Appearance"> <sfnode name="material"> <node type="Material"> <sffield name="diffuseColor"> <color r=".5" g=".5" b=".5"/> </sffield> </node> </sfnode> </node> </sfnode> <sfnode name="geometry"> <node type="Cone"> </node> </sfnode> </node> <node type="TouchSensor" def="dats"> </node> <script def="das"> <interface> <fieldDefinition type="eventIn" fieldType="SFBool" name="inEvent"> </fieldDefinition> <fieldDefinition type="eventOut" fieldType="SFBool" name="outEvent" is="clicked"> </fieldDefinition> </interface> <mffield name="url"> <string>javascript: function inEvent(value, ts) { if (!(value)) outEvent = true; }</string> </mffield> </script> </mfnode> </node> <route fromnode="dats" fromevent="isActive" tonode="das" toevent="inEvent"/> </vrml> </proto> <node type="Background"> <mffield name="groundAngle"> <float value="1"/> </mffield> <mffield name="groundColor"> <color r="0" g="0" b=".4"/> </mffield> <mffield name="skyColor"> <color r="0" g="0" b=".4"/> </mffield> <mffield name="skyAngle"> <float value="1"/> </mffield> </node> <node type="NavigationInfo"> <mffield name="type"> <string>FLY</string> </mffield> </node> <node type="Viewpoint" def="Slide1"> <sffield name="position"> <vec3f x="6" y="-3" z="20"/> </sffield> <sffield name="description"> <string>Slide 1</string> </sffield> </node> <node type="Viewpoint" def="Slide2"> <sffield name="position"> <vec3f x="5" y="-24" z="70"/> </sffield> <sffield name="description"> <string>Slide 2</string> </sffield> </node> <node type="Transform"> <sffield name="translation"> <vec3f x="10" y="-6" z="0"/> </sffield> <mfnode name="children"> <node type="DownArrow" def="Next1"> </node> </mfnode> </node> </vrml> --=_ORCL_26532646_0_0 Content-Transfer-Encoding:7bit Content-Type:text/plain; name="vrml.xsl"; charset="us-ascii" Content-Disposition:attachment; filename="vrml.xsl" <?xml version='1.0'?> <!-- XSL Stylesheet for transforming XML-formatted VRML back into utf8 VRML. Created 12/11/98 by Daniel Lipkin Copyright (c) 1998 by Oracle Corporation. All Rights Reserved. Open issues about this stylesheet (answers are not clear to me from the current XSL spec): - is ' test="!(./*)" ' a legal expression to test for an empty element? - can you match against #PCDATA ? --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <!-- Need to define the output mime type as model/vrml. XSL doesn't yet have an instruction for this --> <xsl:template match="vrml"> #VRML V2.0 utf8 <xsl:process-children/> </xsl:template> <xsl:template match="node"> <xsl:if test="attribute(def)"> DEF <xsl:value-of expr="attribute(def)"/> <xsl:text> </xsl:text> </xsl:if> <xsl:value-of expr="attribute(type)"/> { <xsl:process-children/> } </xsl:value-of> </xsl:template> <xsl:template match="use"> USE <xsl:value-of expr="attribute(node)"/> </xsl:template> <xsl:template match="script"> <xsl:if test="attribute(def)"> DEF <xsl:value-of expr="attribute(def)"/> <xsl:text> </xsl:text> </xsl:if> <xsl:value-of expr="attribute(type)"/> { <xsl:process-children/> } </xsl:value-of> </xsl:template> <xsl:template match="interface"> <xsl:process-children/> </xsl:template> <xsl:template match="fieldDefinition"> <xsl:value-of expr="attribute(type)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(fieldType)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(name)"/> <xsl:text> </xsl:text> <xsl:choose> <xsl:when test="attribute(is)"> IS <xsl:value-of expr="attribute(is)"/> </xsl:when> <xsl:otherwise> <xsl:process-children/> </xs:otherwise> </xsl:choose> </xsl:template> <xsl:template match="externproto"> EXTERNPROTO <xsl:value-of expr="attribute(nodeType)"/> [ <xsl:process match="interface"/> ] <xsl:process match="#PCDATA"/> </xsl:template> <xsl:template match="proto"> PROTO <xsl:value-of expr="attribute(nodeType)"/> [ <xsl:process match="interface"/> ] { <xsl:process match="vrml"/> } </xsl:template> <xsl:template match="sffield"> <xsl:value-of expr="attribute(name)"/> <xsl:text> </xsl:text> <xsl:choose> <xsl:when test="attribute(is)"> IS <xsl:value-of expr="attribute(is)"/> </xsl:when> <xsl:otherwise> <xsl:process-children/> </xs:otherwise> </xsl:choose> </xsl:template> <xsl:template match="mffield"> <xsl:value-of expr="attribute(name)"/> <xsl:choose> <xsl:when test="attribute(is)"> IS <xsl:value-of expr="attribute(is)"/> </xsl:when> <xsl:otherwise> [ <xsl:process-children/> ] </xs:otherwise> </xsl:choose> </xsl:template> <xsl:template match="sfnode"> <xsl:choose> <xsl:when test="attribute(is)"> IS <xsl:value-of expr="attribute(is)"/> </xsl:when> <xsl:otherwise> <!-- Insert a NULL if the element has no children --> <xsl:if test="!(./*)"> NULL</xsl:if> <xsl:process-children/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="mfnode"> <xsl:value-of expr="attribute(name)"/> <xsl:choose> <xsl:when test="attribute(is)"> IS <xsl:value-of expr="attribute(is)"/> </xsl:when> <xsl:otherwise> [ <xsl:process-children/> ] </xs:otherwise> </xsl:choose> </xsl:template> <xsl:template match="bool"> <xsl:value-of expr="attribute(value)"/> </xsl:template> <xsl:template match="color"> <xsl:value-of expr="attribute(r)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(g)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(b)"/> </xsl:template> <xsl:template match="float"> <xsl:value-of expr="attribute(value)"/> </xsl:template> <xsl:template match="image"> <xsl:value-of expr="attribute(width)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(height)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(count)"/> <xsl:text> </xsl:text> <xsl>process-children/> </xsl:template> <xsl:template match="int32"> <xsl:value-of expr="attribute(value)"/> </xsl:template> <xsl:template match="rotation"> <xsl:value-of expr="attribute(axisX)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(axisY)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(axisZ)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(angle)"/> </xsl:template> <xsl:template match="string"> <xsl:process-children/> </xsl:template> <xsl:template match="time"> <xsl:value-of expr="attribute(value)"/> </xsl:template> <xsl:template match="vec2f"> <xsl:value-of expr="attribute(x)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(y)"/> </xsl:template> <xsl:template match="vec3f"> <xsl:value-of expr="attribute(x)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(y)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(z)"/> </xsl:template> <xsl:template match="route"> ROUTE <xsl:value-of expr="attribute(fromnode)"/>.<xsl:value-of expr="attribute(fromevent)"/> TO <xsl:value-of expr="attribute(tonode)"/>.<xsl:value-of expr="attribute(toevent)"/> </xsl:template> </xsl:stylesheet> --=_ORCL_26532646_0_0-- ------------------------------------------------------------------------ for list subscription instructions, send email to dbwork-request@vrml.org with text "info" Next message: Bullard, Claude L: "Re: DTDs for VRML" Previous message: Jeff Sonstein: "Re: Database access with VRML" Next in thread: Bullard, Claude L: "Re: DTDs for VRML"