1  This file was updated on Friday, 2003-06-20 at 10:10 AM
  2  
  3  
  4  ============================================================
  5  xsl_query.jsp
  6  ============================================================
  7  
  8  
  9  <html>
 10  <!--
 11    XSL Query Starter Code for Final 91.513 Assignment
 12    Jesse M. Heines, UMass Lowell Computer Science, heines@cs.uml.edu
 13    updated by JMH on June 20, 2003 at 09:56 AM
 14  -->
 15  <head>
 16    <title>XSL Query Starter Code</title>
 17    
 18  <%!
 19    /** name of XML file to process on the server */
 20    String strXMLFileName ;
 21    
 22    /** full path to the XML file to process on the server */
 23    String strRealXMLFilePath ;
 24  %>
 25    
 26    <%-- include XSL functions defined in an external file --%>
 27    <%@ include file="xsl_functions.jsp" %>
 28  </head>
 29  
 30  <body>
 31  <%
 32    // set main variables here so that they are reinitialized in each independent run
 33    strXMLFileName = "tutorialRoster.xml" ;
 34    strRealXMLFilePath = getRealPath( application, request ) + strXMLFileName ;
 35    
 36    // extract a single piece of data from the XML file
 37    String strTutorialTitle = 
 38        getElementContentFromXML( strRealXMLFilePath, 
 39                                  "tutorialRoster/particulars/title" ) ;
 40    
 41    // extract another single piece of data from the XML file
 42    String strTutorialLocation = 
 43        getElementContentFromXML( strRealXMLFilePath, 
 44                                  "tutorialRoster/particulars/location" ) ;
 45    
 46    // extract multiple pieces of data from the XML file
 47    String strXPath = "//participant/name/@last[starts-with( . , 'P' )]" ;
 48    String[] arrStudents = 
 49        getMultipleElementContentFromXML( strRealXMLFilePath, strXPath ) ;
 50  %>
 51    
 52    <h2>  <!-- copy document title to page header -->
 53      <script type="text/javascript"><!--
 54        document.writeln( document.title ) ;
 55      --></script>
 56    </h2>
 57  
 58    <!-- show time stamps to verify reloading -->
 59    <%
 60      // show date and time from server side to verify that page has loaded
 61      out.println( "<p><i>Server Side Time Stamp:</i>  " + ( new java.util.Date() ) + "<br/>" ) ;
 62    %>
 63    <script type="text/javascript"><!--
 64      // show date and time from client side to verify that page has loaded
 65      document.writeln( "<i>Client Side Time Stamp:</i>  " + new Date() + "</p>" ) ;
 66    --></script>
 67    
 68    <!-- show the full path to the XML file -->
 69    <p>The full path to the XML file on the server is:<br/>
 70       <b><%= strRealXMLFilePath %></b></p>
 71    
 72    <!-- show single data items extracted from the XML file -->
 73    <p>The XML file indicates that the title and location of this tutorial are:<br/>
 74       <b><%= strTutorialTitle %><br/>
 75       <%= strTutorialLocation %></b></p>
 76  
 77    <!-- show multiple data items extracted from the XML file -->
 78    <p>Querying the course roster with the XPath:</p>
 79    <blockquote>
 80      <code><b><%= strXPath %></b></code>
 81    </blockquote>
 82    <p>returns:<br/>
 83      <ol>
 84        <%
 85          for ( int k = 0 ; k < arrStudents.length ; k++ )
 86            out.println( "<li>" + arrStudents[ k ] + "</li>" ) ;
 87        %>
 88      </ol>
 89    </p>
 90  
 91    <p><a href="xsl_query_jsp-listing.htm">View Source</a></p>
 92    
 93    <p>XML File Listing:</p>
 94    
 95    <%= getXMLListing( strRealXMLFilePath ) %>
 96  
 97  </body>
 98  </html>
 99  
100  
101  ============================================================
102  xsl_functions.jsp
103  ============================================================
104  
105  
106  <%--
107    XSL Helper Functions for Applying XSL Strings to XML Files
108    Jesse M. Heines, UMass Lowell Computer Science, heines@cs.uml.edu
109    updated by JMH on June 18, 2003 at 09:12 PM
110  --%>
111  
112  <%@ page import="java.io.*" %>                      <%-- for StringWriter and File    --%>
113  <%@ page import="java.util.*" %>                    <%-- for StringTokenizer          --%>
114  <%@ page import="javax.xml.transform.*" %>          <%-- for Transformer classes      --%>
115  <%@ page import="javax.xml.transform.stream.*" %>   <%-- for some XSL transformations --%>
116  <%@ page import="org.apache.xml.serialize.*" %>     <%-- for OutputFormat             --%>
117  <%@ page import="org.w3c.dom.*" %>                  <%-- for Document                 --%>
118  <%@ page import="org.apache.xerces.parsers.*" %>    <%-- for DOMParser and SAXParser  --%>
119  <%@ page import="java.awt.*, javax.swing.*" %>      <%-- for debugging windows        --%>
120  
121  <%!
122    /** This function can be used for debugging to display messages in a simple dialog box.
123     *  Note that it only works on a Windows-based server, not a Unix-based one.
124     *  @param  str  string to display
125     */
126    public void show( String str )
127    {
128      JOptionPane.showMessageDialog( null, str,
129          "Debugging Information", JOptionPane.INFORMATION_MESSAGE ) ;
130    }
131  
132    
133    /** This function returns the real path to the directory containing currently running JSP.
134     *  @param  application  the standard application object
135     *  @param  request      the standard request object
136     *  @return String containing the real path in the current OS's format with a "/" appended
137     */
138    public String getRealPath(
139        ServletContext application,   // the standard application object
140        HttpServletRequest request    // the standard request object
141      )
142    {
143      // use request and application objects to get the real path on the server
144      String strRealPath = request.getServletPath() ;
145      strRealPath = strRealPath.substring( 0, strRealPath.lastIndexOf( "/" ) ) ;
146      strRealPath = application.getRealPath( strRealPath ) ;
147  
148      // append the approprate slash for the server's operating system
149      strRealPath += System.getProperty( "file.separator" ) ;
150      
151      // return the result
152      return strRealPath ;
153    }
154  
155  
156    /** Apply an XPath String to an XML file and return the results as a String.
157     *  @param  strXMLfile    String containing full URL to the XML file 
158     *  @param  strXSLstring  String XSL to be applied
159     *  @return String containing the output of the transformation
160     */
161    String ApplyXSLstring( String strXMLfile, String strXSLstring )
162    {
163      return ApplyXSLstring( strXMLfile, strXSLstring, null ) ;
164    }
165  
166  
167    /** Apply an XSL String to an XML file and return the results as a String.
168     *  @param  strXMLfile    String containing full URL to the XML file 
169     *  @param  strXSLstring  String XSL to be applied
170     *  @param  arrParams     2D array of parameter name and value Strings
171     *  @return String containing the output of the transformation
172     */
173    String ApplyXSLstring( String strXMLfile, String strXSLstring, String[][] arrParams )
174    {
175      StringWriter swResult = new StringWriter() ;
176      
177      try {
178        // Use the static TransformerFactory.newInstance() method to get a reference to 
179        // a TransformerFactory
180        TransformerFactory tFactory = TransformerFactory.newInstance();
181    
182        // Use the TransformerFactory to instantiate a Transformer that will work
183        // with the stylesheet you specify
184        Transformer transformer = 
185            tFactory.newTransformer( new StreamSource( new StringReader( strXSLstring ) ) ) ;
186    
187        // Set parameters to pass to the top level of the XSL file
188        if ( arrParams != null )
189          for ( int k = 0 ; k < arrParams.length ; k++ )
190            transformer.setParameter( arrParams[k][0], arrParams[k][1] ) ;
191  
192        // Use the Transformer to apply the associated XSL file to an XML document and write 
193        // the output to an output stream
194        transformer.transform( new StreamSource( strXMLfile ),
195                               new StreamResult( swResult ) ) ;
196  
197        // Return the result
198        return swResult.toString() ;
199  
200      } catch ( TransformerConfigurationException tfce ) {
201        return tfce.toString() ;
202  
203      } catch ( TransformerException tfe ) {
204        return tfe.toString() ;
205      }
206    }
207  
208  
209    /** Extract element content from a specified XML file given an XPath.
210     *  @param  strXMLFile  name of XML file from which to extract data
211     *  @param  strXPath    XPath to data to extract
212     *  @return String element content
213     */
214    String getElementContentFromXML( String strXMLFile, String strXPath )
215    {
216      // convert single quotes to double quotes to allow both to be in XPath filters
217      strXPath = strXPath.replaceAll( "'", "\"" ) ;
218      
219      // query result to be returned to calling function
220      String strResult = ApplyXSLstring( strXMLFile, 
221          "<?xml version='1.0' ?>" +
222          "<xsl:stylesheet version='1.0' " +
223          "         xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" +
224          "  <xsl:template match='/'>" +
225          "    <xsl:value-of select='" + strXPath + "' />" +
226          "  </xsl:template>" +
227          "</xsl:stylesheet>" ) ;
228  
229      // remove initial directive (ending with ">") and remove leading and trailing white space
230      strResult = strResult.substring( strResult.indexOf( ">" ) + 1 ).trim() ;
231      
232      return strResult ;  // return final result
233    }
234  
235  
236    /** Extract content from multiple elements from an XML file given an XPath.
237     *  @param  strXMLFile    name of XML file from which to extract data
238     *  @param  strXPath      XPath to data to extract
239     *  @return String array containing multiple element content
240     */
241    String[] getMultipleElementContentFromXML( String strXMLFile, String strXPath )
242    {
243      // convert single quotes to double quotes to allow both to be in XPath filters
244      strXPath = strXPath.replaceAll( "'", "\"" ) ;
245      
246      // string to delimit multiple results for subsequent tokenizing
247      String strDelimiter = "|" ;
248  
249      // query result to be returned to calling function
250      String strResult = ApplyXSLstring( strXMLFile, 
251          "<?xml version='1.0' ?>\n" +
252          "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>\n" +
253          "  <xsl:template match='/'>\n" +
254          "    <xsl:apply-templates select='" + strXPath + "' />\n" +
255          "  </xsl:template>\n" +
256          "  <xsl:template match='" + strXPath + "'>\n" +
257          "    " + strDelimiter + "<xsl:value-of select='.' />" + 
258          "  </xsl:template>\n" +
259          "</xsl:stylesheet>\n" ) ;
260          
261      // remove initial directive (ending with ">") and remove leading and trailing white space
262      strResult = strResult.substring( strResult.indexOf( ">" ) + 1 ).trim() ;
263      
264      // break result into tokens with which to populate array to be returned
265      StringTokenizer st = new StringTokenizer( strResult, strDelimiter ) ;
266  
267      // populate array to be returned with the results found
268      String[] strArrayResult = new String[ st.countTokens() ] ;
269      for ( int k = 0 ; st.hasMoreTokens() ; k++ )
270        strArrayResult[ k ] = st.nextToken().trim() ;
271        
272      return strArrayResult ;  // return final result
273    }
274  
275  
276    /** Return a String containing an XML file in serialized form.
277     *  @param  strXMLFile    name of XML file from which to extract data
278     *  @return String the XML file in serialized form
279     */
280    String getXMLListing( String strXMLFile )
281    {
282      // open XML file
283      Document doc = null ;                     // the XML document in the specified file
284      File fileXML = new File( strXMLFile ) ;   // the File object for the XML file to open
285      if ( ! fileXML.exists() )
286        return "File " + strXMLFile + " does not exist." ;
287      else
288      {
289        // instantiate the XML parser
290        DOMParser parser = new DOMParser() ;
291    
292        try {      // inherited from class XMLParser
293          parser.parse( strXMLFile ) ;
294        } catch ( IOException e ) {
295            return "<p>XML File Load Error:  " + e.toString() + "</p>" ;
296        } catch ( org.xml.sax.SAXException e ) {
297            return "<p>XML File Parsing Error:  " + e.toString() + "</p>" ;
298        } catch ( Exception e ) {
299            return "<p>Undetermined Error:  " + e.toString() + "</p>" ;
300        }
301        
302        doc = parser.getDocument() ;
303      }
304  
305      // make a serializable version of the XML Document object
306      // reference:  www-106.ibm.com/developerworks/xml/library/x-injava2/?dwzone=xml
307      OutputFormat of = new OutputFormat( doc ) ;
308      of.setIndenting( true ) ;
309      of.setIndent( 2 ) ;
310      of.setPreserveSpace( true ) ;
311      StringWriter sw = new StringWriter() ;
312        // use a StringWriter instead of serializing directly to the 
313        // ObjectOutputStream because serializing directly yields a 
314        // java.io.OptionalDataException when reading the data with 
315        // ObjectInputStream.readObject()
316      XMLSerializer xmlser = new XMLSerializer( sw, of ) ;
317      try {
318        xmlser.serialize( doc ) ;
319      } catch ( IOException ioe ) {
320         return "<p>IOException in getXMLListing:<br/>   " + ioe.toString() ;
321      }
322      
323      // format the string for HTML output
324      String strDoc = sw.toString() ;
325      return "<pre>\n" + strDoc.replaceAll( "<", "&lt;" ) + "\n</pre>" ;
326    }
327  %>
328  
329  
330  ============================================================