MSXML3.0 Support for XSLT

MSXML3.0 provides support for XSL transformations without any additional software. The parser features a transformNode method that usually accepts a stylesheet as a parameter (in DOM form) and returns the result of processing the current document with the supplied stylesheet. For example:

objXML = win32com.client.Dispatch("MSXML2.DOMDocument.3.0")
objXSL = win32com.client.Dispatch("MSXML2.DOMDocument.3.0")
strTransformedXML = objXML.transformNode(objXSL)

In the simplest case, as shown in the preceding code, two DOM instances are created. One DOM instance is needed to hold the source document, the other contains the stylesheet. To get the result of the transformation, call transformNode on the source DOM, providing the stylesheet DOM as a parameter.

Source XML

Example E-4 shows 1999temps.xml, a document containing monthly average temperatures for Woodinville, Washington. This is a simple XML document with a flat structure.

Example E-4. 1999 temps.xml
<CalendarYear value="1999" data="Average Monthly Highs">
  <Month name="January">45.0</Month>
  <Month name="February">49.5</Month>
  <Month name="March">52.7</Month>
  <Month name="April">57.2</Month>
  <Month name="May">63.9</Month>
  <Month name="June">69.9</Month>
  <Month name="July">75.2</Month>
  <Month name="August">75.2</Month>
  <Month name="September">69.3</Month>
  <Month name="October">59.7</Month>
  <Month name="November">50.5</Month>
  <Month name="December">45.1</Month>
</CalendarYear>

There are attributes indicating the year on record, and the type of data displayed. The Month elements have a name attribute, while the actual temperature is character data.

XSL Stylesheet

With your stylesheet, attempt to find the average yearly temperature, based on the average monthly temperatures. Using a combination of XPath’s sum function and div operator yields the results needed. Example E-5 shows the stylesheet temps.xsl.

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

<xsl:variable name="average" 
     select="sum(//CalendarYear/Month/text(  )) div 12"/>
<xsl:template match="/">
<html>
<body>
  <p>
  <font face="tahoma,arial,helvetica" size="2">
    <xsl:value-of select="/CalendarYear/@data"/> for
    <xsl:value-of select="/CalendarYear/@value"/>:
  </font>
  </p>
  <table border="1" 
         bordercolor="#000000"
         cellpadding="5" 
         cellspacing="0" 
         width="350">
    <xsl:apply-templates/>
    <tr>
      <td colspan="2" bgcolor="#88BBEE" width="350" 
          align="right">
        <p>
          <font face="tahoma,arial,helvetica" size="2">
            <b>Average: 
              <xsl:value-of select="format-number($average, '0.00')"/>
            </b>
          </font>
        </p>
       </td> 
    </tr>
  </table>
</body>
</html>
</xsl:template>

<xsl:template match="Month">
  <tr>
    <td bgcolor="#CCCCCC" width="325" align="left">
      <p>
        <font face="tahoma,arial,helvetica" size="2">
          Month: <b><xsl:value-of select="@name"/></b>
        </font>
      </p>
    </td> 
    <td bgcolor="#CCCCCC" width="25" align="left">
      <p>
        <font face="tahoma,arial,helvetica" size="2">
          <b><xsl:value-of select="./text(  )"/></b>
        </font>
      </p>
    </td>
  </tr>
</xsl:template>

</xsl:stylesheet>

The stylesheet performs its computational work in two parts. First, a variable is created that holds the average of the temperatures by using the sum function to add them together, then using the div operator to divide between the total number of months in a year:

<xsl:variable name="average" 
     select="sum(//CalendarYear/Month/text(  )) div 12"/>

Finally, some formatting is performed within a template by calling format-number, using $average as a parameter:

<xsl:value-of select="format-number($average, '0.00')"/>

This ensures that the temperature figure contains at least two floating-point digits.

Running an MSXML Transformation

To apply the transformation from Python, create two instances of MSXML3.0, and supply one with the source XML and one with the stylesheet. Then use transformNode to complete the transformation process. Example E-6 shows transform.py, which completes the task.

Example E-6. transform.py
"""
 transform.py - using MSXML3.0
 XSLT support from Python
"""
import win32com.client

strSourceDoc = "1999temps.xml"
strStyleDoc  = "temps.xsl"

objXML = win32com.client.Dispatch("MSXML2.DOMDocument.3.0")
objXSL = win32com.client.Dispatch("MSXML2.DOMDocument.3.0")

if (not objXML.load(strSourceDoc)):
  print "Error loading", strSourceDoc

if (not objXSL.load(strStyleDoc)):
  print "Error loading", strStyleDoc

strTransformedXML = objXML.transformNode(objXSL)
print strTransformedXML

You can run the process from a command prompt, and write the output to an HTML file if you want to view the results in a browser.

>c:python21python transform.py > temps.html

Figure E-1 shows the transformed XML residing in a browser.

The result of the transformation
Figure E-1. The result of the transformation
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.226.121