DTDs for VRML


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"