Generating the XSL | WebReference

Generating the XSL

Back Contents Next

Generating the XSL

Now let's start looking at the process of generating the XSL file.

 

Normal XML rules apply. The XML generated by our ASP page must be well-formed, which means that case matters.

 

There are two approaches we could use in order to meet our goal of creating the XSL:

 

q         We could build a string

q         We could create an instance of the XML DOM, build a result tree and write out the XML as a string

Either approach is valid for our needs. The first is simpler, and may be faster, but it is a limited solution. Should we wish to revisit this application at some point in the future and extend its functionality, our options would very restricted. Furthermore, we would be limited to a linear building process, and it would be cumbersome to dynamically modify any part of the result string that had already been built. It would be difficult, for example, to add the capability of converting an attribute in the source document to an element in the result. By taking the XML DOM approach, all of the capabilities of the DOM are available to us, and we are not limited to a sequential result. Plus, it's more of an XML-purist approach to the problem.

 

So, we will need two instances of the XML DOM. The first will contain the result tree we will be building, whose XML source will ultimately become our return value, and the second instance will host the XML translation document that will drive the creation process.

 

As you're looking through the discussion of how this ASP page works, you may find it useful to refer to the end result, which is shown here as rendered in Internet Explorer 5, with the color coding and indentation provided by IE's default internal style sheet.

 

 

If you download the source code for this book and look at the interpreter.asp file in your browser, this is what you should see.

 

As is always the case when we use an ASP to generate XML, we need to set the response type:

 

<%

Response.ContentType = "text/xml"

Response.Expires = 0

 

dim result

dim interpreter

dim oNodes

 

Next we will create our required two instances of the XML DOM, and load in the interpreter.xml file (our mapping file):

 

Set result = Server.CreateObject("Microsoft.XMLDOM")

 

Set interpreter = Server.CreateObject("Microsoft.XMLDOM")

interpreter.async = false

'// load the definition file

sSource = Server.MapPath("interpreter.xml")

interpreter.load(sSource)

  

'// did the XML file load OK?

If interpreter.parseError.errorCode <> 0 Then

           msg = "<msg><gen>Error loading INTERPRETER data file.</gen>"

           msg = msg & "<br>Description: " & interpreter.parseError.reason &

                 "</br>"       

           msg = msg & "<br>Source text: " & interpreter.parseError.srcText &

                 "</br></msg>"         

           Response.Write msg

End If

...

 

Note that as this code is running server-side, we need to provide a physical path to the XML file that we are loading, which is done by using Server.MapPath. We set the async property of the interpreter file to false, as we cannot process anything until this file is completely loaded. The async property of the result tree is irrelevant.

 

Next we extract all of the <xlat> nodes from our definition tree:

 

Set oNodes = interpreter.documentElement.selectNodes("//xlat")

 

Now we are ready to start populating our result tree. The first step is to add the node that identifies this XML document as a style sheet:

 

'// add a node to the result tree for the stylesheet declaration

Set oNewNode = result.createNode("element","xsl:stylesheet", _

                                   "http://www.w3.org/TR/WD-xsl")

result.appendChild(oNewNode)

 

Then we set the root element, the stylesheet declaration, as follows:

 

'// the stylesheet declaration is the outermost grouping tag. It is the root

'// element and parent to all other elements

Set root = result.documentElement

 

If you refer back to the IE5 view of the XSL shown in the previous figure, you'll see that the next entry is <xsl:template match="/">, which we create as follows:

 

'// create the XSL node

Set oTemp = result.createNode("element","xsl:template", _

                                  "http://www.w3.org/TR/WD-xsl")

oTemp.setAttribute "match", "/"

root. appendChild(oTemp)

 

Rather than hard-coding the names of the root document and the item of the translation result (<shipments> and <shipment> in our example), we extract those tag names from the definition file. This is based on the assumption that the root element of the definition file will also be the root element of the translation result:

 

 

 

 

 

 

 

'// name of the container tag (eg: "shipments")

nodeName = interpreter.documentElement.firstChild.nodeName

Set oContainer = result.createNode("element", _

                                    interpreter.documentElement.nodeName,"")

oTemp.appendChild(oContainer)

 

Note that we have created the oContainer variable, which represents the root element (shipments) of the translated result.

 

Now we need to add a line to our XSL result tree that when processed will tell the XSL to iterate through all instances of the children (shipment) of that root. The following code will create an element containing <xsl:for-each select="//shipment"> and append it to the result tree:

 

Set oLoop = result.createNode("element","xsl:for-each", _

                                 "http://www.w3.org/TR/WD-xsl")

oLoop.setAttribute "select", "//" & nodeName

oContainer.appendChild(oLoop)

 

Next we create an entry for the contained item (that is <shipment>) and append it to the result tree:

 

Set oLoopParent = result.createNode("element",nodeName, "")

oLoop.appendChild(oLoopParent)

 

Now we get to the real work. In this section of the code, we iterate through each of the <xlat> mapping elements. For each one, we create an element using the name attribute of the <out> element, and an <xsl:value-of> from the select attribute from the <in> element. These items are added to the result tree.

 

An example of one of these would be:

 

<shippedby><xsl:value-of select="carrier"/></shippedby>

 

For Each oNode in oNodes

  Set oNewNode = result.createNode("element", _

                     oNode.selectSingleNode("out").getAttribute("name"), "")

  Set oSelect = result.createNode("element",_

                               "xsl:value-of","http://www.w3.org/TR/WD-xsl")

  oSelect.setAttribute "select",oNode.selectSingleNode("in").getAttribute("name")

  oNewNode.appendChild(oSelect)

  oLoopParent.appendChild(oNewNode)

Next

 

Finally, we need to add the apply-templates node:

 

Set oNode = result.createNode("element","xsl:apply-templates",

                                              "http://www.w3.org/TR/WD-xsl")

oTemp.appendChild(oNode)

 

We have now completely built our result tree, and we return it to the calling application (which could be a browser, a script, an XML file, etc):

 

Response.Write result.xml

%>

 

 

 

 

 

 

 

 

If you are considering adapting this procedure for your own project, then the first stage should be to create an XSL file that gets the data from the XML document. This way you can get the display right before you start writing your interpretation code.


BackContentsNext
©1999 Wrox Press Limited, US and UK.

http://www.internet.com


Produced by Michael Claßen
All Rights Reserved. Legal Notices.

URL: http://www.webreference.com/xml/resources/books/professionalaspxml/40281003.htm
Created: Jan. 05, 2001
Revised: Jan. 05, 2001