Michelle Yuan-- Shapes Using XSL TransformationsDescription of Deliverable #2In 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> 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: 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: 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: HTMLUsing 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 SourceThe 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> |