Chris Pollett > Students >
Michelle Yuan

    ( Print View )

    [Bio]

    [CS297Proposal]

    [Del1]

    [Del2]

    [Del3]

    [CS297Report]

    [CS298Proposal]

    [CS298Presentation]

    [CS298Report]

                           

























Michelle Yuan-- Shapes Using XSL Transformations

Description of Deliverable #2

In deliverable #2, I create input file which is tag based XML file, and use its DTD file to check whether the XML input file is valid or not. Then I apply XSL Transformation stylesheet to render the input file into the VRML file and display on the screen.

Shape Markup Language (ShML) and DTD:

ShML is a XML tag based input file, and it has three pairs of tags:

<SQUARE> <CIRCLE> <TRIANGLE>
</SQUARE> </CIRCLE> </TRIANGLE>

The meaning of a pair of tags is to draw that kind of shape in the current enclosing shape. Triangles should be drawn in blue; circles should be drawn in green; and squares should be drawn in red. If there is no enclosing shape the shape should be drawn directly on the frames background.

For example, if the ShML XML file was the following:
<SQUARE>
<CIRCLE> </CIRCLE>
<TRIANGLE> </TRIANGLE>
</SQUARE>
<SQUARE>
</SQUARE>

Then two non-overlapping squares would be drawn centered on the screen. In the interior of the first square, would be drawn in a non-overlapping manner a circle and triangle. In ShML file, if it involves any non-space symbols other than those in tags or if the open and close tags mismatch then it will report error when you try to open XML file in IE. This grammar rule is defined in DTD file. The empty <CIRCLE> </CIRCLE> is same as <CIRCLE />

Example of mismatched tags:
<SQUARE>
<CIRCLE>
</CIRCLE>
</TRIANGLE>
</SQUARE>

Example of entire of XML input file:
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE FIGURES SYSTEM "ShMLDTD.dtd">
<?xml-stylesheet type="text/xsl" href="ShML.xsl"?>
<ShML>
<SQUARE>
<TRIANGLE>
<CIRCLE />
<SQUARE />
</TRIANGLE>
<CIRCLE>
</CIRCLE>
</SQUARE>
</ShML>

XSL Transformation:

In XSL Transformation part, I mainly use the <xsl:with-param> and <xsl:param> elements to define parameters and pass them into the low level to calculate the position each time I used to transform the shape in VRML.

<xsl:with-param> element:

<xsl:with-param> element defines a parameter to be passed to a template. When the template is invoked, values can be passed in for the parameter. The <xsl:with-param> element has to appear inside an <xsl:apply-templates> or <xsl:call-template> element. It has the required attribute name, which specifies the name of the parameter. It also has the optional attribute select, which specifies the value of the parameter. There are three ways to define the value of parameter by using <xsl:with-param> element.

First, if the <xsl:with-param> element is empty and does not contain a select attribute, then no value is passed to the template.

Second, if the <xsl:with-param> element is empty and has a select attribute, the value of the paramter is the value of the select attribute.

Third, if the <xsl:with-param> element contains an XSLT template, the value of the parameter is the result of processing the template.

If no value is passed to the template (<xsl:with-param name="x" />), then the default value of the parameter, if any, is used instead. The default value of the parameter is defined on the <xsl:param> element inside the <xsl:template> itself.

<xsl:param> element:

<xsl:param> element defines the name and value of a parameter to be used by a template. It can appear as a top-level element, which is a global parameter visible to all areas of the stylesheet. It can also appear inside the <xsl:template> element. The value of the parameter can be defined in one of two ways: specified in the select attribute, or defined in an XSLT template inside the <xsl:param> element itself.

During the rendering processor, I also use the XPath expression, function and operators to get the number of nodes in the current directory and the position of the node so that I can calculate all children nodes position in VRML.

For example:
<xsl:param name ="position" select = "position()" />
<xsl:param name = "x" select ="($position - 1) * $side" />
<xsl:param name="numNodes" select="count(*)"/>
<xsl:param name = "childScaleFactor" select = "$side div $numNodes " />

HTML

Using XSLT stylesheet to translation ShML markup language into a HTML format so that cortona VRML browser could be open automatically. In this assignment, we create a BUTTON to handle opening Cortona VRML browser. All the VRML code are written into script function main( ) by using document.write. For example: doc.writeln(" #VRML V2.0 utf8 "). Using the other two java script functions: closeVrmlDocument( ) and getVrmlDocument(doc) to open VRML browser and display its contents. When the BUTTON is been click, the 3D picture is display on the screen.

Following is an example of output for deliverable #2 To see this demo you need the following plug-in: Cortona

An example Shape XML file

Source

The Shape DTD:

<!-- ***************************************
             ###   Deliverable # 2   ###
             
     FileName: ShMLDTD.dtd
     Student: Jing Yuan
     Date: 4/01/02
 
     ***************************************  -->

<!ELEMENT ShML ( TRIANGKE | CIRCLE | SQUARE )* >

<!ELEMENT TRIANGLE ( CIRCLE | SQUARE | TRIANGLE )* >

<!ELEMENT CIRCLE ( SQUARE | TRIANGLE | CIRCLE )* >

<!ELEMENT SQUARE ( CIRCLE | TRIANGLE | SQUARE )* >



An example Shape document:

<?xml version="1.0"  standalone="yes"?>

<!DOCTYPE FIGURES SYSTEM "ShMLDTD.dtd">
<?xml-stylesheet type="text/xsl" href="ShML.xsl"?>


<!-- ***************************************
             ###   Deliverable # 2   ###
             
     FileName: ShML.xml
     Student: Jing Yuan
     Date: 4/01/02
     
     ***************************************  -->

<ShML>

     <SQUARE>
        <TRIANGLE>
        </TRIANGLE>
        <CIRCLE>       
        </CIRCLE>
        <CIRCLE />
     </SQUARE> 

</ShML>

The stylesheet transformation:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<!-- *******************
     Deliverable # 2               
     FileName: ShML.xsl
     Student: Jing Yuan
     Date: 4/01/02
     Description: 
     *******************  -->

<xsl:output method="html" indent="yes" />  


<!-- ****** root ****** -->
<xsl:template match="/">
     <xsl:apply-templates select="ShML" />                 
</xsl:template>


<!--    Start to process <ShML> tag     -->   
<xsl:template match="ShML">  

<!-- *******************************************************
      when it's <ShML> tag, then start to create HTML file 
      that opens VRML broswer. 
      Then create: VRML header, Group, and children node.
     *******************************************************  -->
     
  <html>
     <head>
	<script language="javascript">
	
	function closeVrmlDocument() {
	     var d = this.doc;
	     d.open("text/html");
	   
	     d.write('<body leftmargin='0' topmargin='0' scroll='no'>');
	     d.write(
              '<object id='Cortona' width='100%' height='100%'
classid='clsid:86A88967-7A20-11D2-8EDA-00600818EDB1'>');
    
	     d.write('</object></body>');
	     d.close();
	     var e = d.all["Cortona"].Engine;
	     e.RootNodes.Add(e.CreateVrmlFromString(this.syntax));
	}
	
	function getVrmlDocument(doc) {
	     var isIE = navigator.appVersion.indexOf("MSIE") != -1;
	
	     if (!isIE)
	        return doc;
	
	     var adapter = new Object();
	     adapter.open = new Function("mimetype", "return;");
	     adapter.write = new Function("s", "this.syntax += s;");
	     adapter.writeln = new Function("s", 
"this.syntax += s; this.syntax +='\\n';");
	     adapter.close = closeVrmlDocument;
	     adapter.doc = doc;
	     adapter.syntax = "";
	     
	     return adapter;
	}
	
	function main() {
	     var wnd = window.open("about:blank", "_blank");
	     var doc = getVrmlDocument(wnd.document);
	
	     doc.open("model/vrml");
	
	     doc.writeln(" #VRML V2.0 utf8 ");
	     doc.writeln("Group {    children [ ");
	     
	     <!-- process children nodes -->
             <xsl:apply-templates select="*" >    
                  <!-- declare golbal parameters -->
                  <xsl:with-param name = "scaleFactor" select = "1.0" />
                  <xsl:with-param name = "side" select = "1.0" />        
             </xsl:apply-templates >  
             
             doc.writeln(" ]   } ");	
	     doc.close();
	}
		
	</script>
     </head>
     <body>
	 <form><xsl:element 
name="input" use-attribute-sets="attribs" /></form>
     </body>
  </html>     
                                  
</xsl:template>


<!-- ********************************************************
     Creating the attribute-set for element <input> as below:
     <input type="button" value="main" onclick="main()">
     ********************************************************    -->

<xsl:attribute-set name="attribs">
<xsl:attribute name="type">BUTTON</xsl:attribute>
<xsl:attribute name="value"><xsl:text>Click to 
see VRML transformed document</xsl:text></xsl:attribute>
<xsl:attribute 
name="onclick"><xsl:text>main()</xsl:text></xsl:attribute>
</xsl:attribute-set>


<!-- ***************************************************
     Starting the shape element tag 
     Create square shape if the element is <SQUARE>
     ***************************************************  -->

<xsl:template match="SQUARE">

      <!-- parameters pass from top level -->       
      <xsl:param name = "scaleFactor" />       
      <xsl:param name = "side" />  
      
      <!-- Declare local parameter, start from 0.0 -->      
      <xsl:param name = "startX" select="0.0" />
      
      <xsl:param name ="position" select = "position()" />  
      <xsl:param name = "x" 
select ="$startX + ($position - 1) * $side" />         
      <xsl:param name = "xCenter" select = " $x + ($side div 2)" />      
      <xsl:param name="numNodes" select="count(*)"/>      
      
      <xsl:param name = "childScaleFactor" 
select = "$side div $numNodes " />      
      <xsl:param name = "childSide" select = "$side div $numNodes" />
     
     <!-- ************************************
          VRML code for create Transform node
          ************************************  -->
     
      doc.writeln("Transform { ");
      doc.writeln(
"translation <xsl:value-of select = "$xCenter" /> 0.0 0.0 ");
      doc.writeln(
"scale<xsl:text> </xsl:text><xsl:value-of select="$scaleFactor" 
/><xsl:text> </xsl:text><xsl:value-of 
select="$scaleFactor" /><xsl:text> 
</xsl:text><xsl:value-of select="$scaleFactor" 
/><xsl:text> </xsl:text>");
      
      <!-- Square shape VRML code -->
      doc.writeln(
"children [ Shape { appearance Appearance 
{ material Material { diffuseColor 1.0 0.0 0.0 transparency 0.5 } } 
geometry IndexedFaceSet { coord Coordinate 
{ point [  -0.5 -0.5 0.0,  0.5 -0.5 0.0 0.5  
0.5 0.0, -0.5  0.5 0.0 ] } coordIndex [ 0, 1, 2, 3] } } ] }, ");
      
     <!-- *******************************************************
          Recursive call apply-templates to process child element
          *******************************************************  -->

      <xsl:apply-templates select="*" >
          <!-- pass parameter into next level -->
          <xsl:with-param name="side" select="$childSide" />
          <xsl:with-param 
name = "scaleFactor" select = "$childScaleFactor" />
          <xsl:with-param name = "startX" select = "$x" />
      </xsl:apply-templates>      
     
</xsl:template>
    

<!-- **************************************************
     Create triangle shape if the element is <TRIANGLE>    
     **************************************************   -->
     
<xsl:template match="TRIANGLE">
      
      <!-- parameters pass from top level -->      
      <xsl:param name = "scaleFactor" />      
      <xsl:param name = "side" />   
      
      <!-- Declare local parameter, start from 0.0 -->     
      <xsl:param name = "startX" select="0.0" /> 
      
      <xsl:param name ="position" select = "position()" /> 
      <xsl:param name = 
"x" select ="$startX + ($position - 1) * $side" />        
      <xsl:param name = "xCenter" select = " $x + ($side div 2)" />     
      <xsl:param name="numNodes" select="count(*)"/>     
      
      <xsl:param name = 
"childScaleFactor" select = "$side div $numNodes " />     
      <xsl:param name = "childSide" select = "$side div $numNodes" />    

     <!-- ************************************
          VRML code for create Transform node
          ************************************  -->
     
       doc.writeln("Transform { ");
       doc.writeln(
"translation <xsl:value-of select = "$xCenter" /> 0.0 0.0 ");
       doc.writeln(
"scale<xsl:text> </xsl:text><xsl:value-of select="$scaleFactor"
 /><xsl:text> </xsl:text><xsl:value-of select="$scaleFactor"
 /><xsl:text> </xsl:text><xsl:value-of select="$scaleFactor" 
/><xsl:text> </xsl:text>");
       
       <!-- Triangle shape VRML code -->
       doc.writeln("children [ Shape { appearance Appearance 
{ material Material { diffuseColor 0.0 0.0 1.0 transparency 0.5 } } 
geometry IndexedFaceSet { coord Coordinate { 
point [ -0.5 -0.5 0.0, 0.5 -0.5 0.0 0.0 0.5 0.0, -0.5 0.5 0.0 ] } 
coordIndex [ 0, 1, 2] } } ] }, ");
      
  <!-- *******************************************************
       Recursive call apply-templates to process child element
       *******************************************************  -->

      <xsl:apply-templates select="*" >
          <!-- pass parameter into next level -->
          <xsl:with-param name="side" select="$childSide" />
          <xsl:with-param name = "scaleFactor" 
select = "$childScaleFactor" />
          <xsl:with-param name = "startX" select = "$x" />
      </xsl:apply-templates>
      
</xsl:template>
                

<!-- ***********************************************
     ***********************************************
     Create circle shape if the element is <CIRCLE>
     ***********************************************     
     ***********************************************  -->
<xsl:template match="CIRCLE">

      <!-- parameters pass from top level -->       
      <xsl:param name = "scaleFactor" />       
      <xsl:param name = "side" />       
      
      <!-- Declare local parameter, start from 0.0 -->      
      <xsl:param name = "startX" select="0.0" />   
      
      <xsl:param name ="position" select = "position()" />  
      <xsl:param name = "x" select ="$startX + ($position - 1) *$side"/> 
      <xsl:param name = "xCenter" select = " $x + ($side div 2)" />      
      <xsl:param name="numNodes" select="count(*)"/>      
      
      <xsl:param name="childScaleFactor" select="$side div $numNodes"/>
      <xsl:param name = "childSide" select = "$side div $numNodes" />    

     <!-- ************************************
          VRML code for create Transform node
          ************************************  -->
    
       doc.writeln("Transform { ");
       doc.writeln(
"translation <xsl:value-of select = "$xCenter" 
/> 0.0 0.0 rotation 1.0 0.0 0.0 1.571 
scale<xsl:text> </xsl:text><xsl:value-of 
select="$scaleFactor" /><xsl:text> 
</xsl:text><xsl:value-of select="$scaleFactor" 
/><xsl:text> </xsl:text><xsl:value-of select="$scaleFactor" 
/><xsl:text> </xsl:text>");
       
       <!-- Circle shape VRML code -->
       doc.writeln(
"children [ Shape { appearance Appearance { material Material 
{ diffuseColor 0.0 1.0 0.0 transparency 0.5 } } geometry 
Cylinder { radius 0.5 height 0.01 } } ] }, ");

  <!-- *******************************************************
       Recursive call apply-templates to process child element
       *******************************************************  -->
      
      <xsl:apply-templates select="*" >
          <!-- pass parameter into next level -->
          <xsl:with-param name="side" select="$childSide" />
          <xsl:with-param name = "scaleFactor" 
select = "$childScaleFactor" />
          <xsl:with-param name = "startX" select = "$x" />
      </xsl:apply-templates>
             
</xsl:template>
                            
</xsl:stylesheet>