You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by Ry...@stpaul.com on 2002/03/28 15:50:07 UTC

Please Help! Trouble with Custom XMLReader

Hello,

I am trying to write a custom XMLReader that implements
org.xml.sax.XMLReader.  I want to read records off the database and produce
SAX events for each record in the query result, then merge those events
with a style sheet to produce HTML.

I wanted to start slowly and work my way up.  To do so, I wanted to first
get everything working using hard-coded values.  But I can't get things to
work even using the simple hard-coded values!!  The problem is that the XML
isn't getting merged with the XSL style sheet -- the HTML from the style
sheet is displayed in the browser, but without any XML data.


Here's the sample XML I want to parse:

===========================
Listing 1 -- discussionForumHome.xml  (Note style sheet reference is
commented out)
===========================
<?xml version="1.0" encoding="UTF-8"?>
<!--  <?xml-stylesheet type="text/xsl" href="discussionForumHome.xslt"?>
-->
<discussionForumHome>
      <messageBoard id="1" name="Java Programming"/>
      <messageBoard id="2" name="XML Programming"/>
      <messageBoard id="3" name="XSLT Questions"/>
</discussionForumHome>



Very simple.  Here's what the parse() method of my XMLReader implementing
class looks like.  Note everything is hard-coded for testing:

===========================
Listing 2
===========================
public void parse(org.xml.sax.InputSource input) throws
java.io.IOException, org.xml.sax.SAXException {

      //************************
      //NOTE: input is not used here, for testing purposes
      //************************

      //*********************************
      //NOTE: EMPTY_ATTR is an instance of AttributesImpl
      //*********************************

      ContentHandler contentHandler = getContentHandler();

      if(contentHandler == null) {
            return;
      }

      //Start the document
      contentHandler.startDocument();

      //Create the document root
      contentHandler.startElement("", "", "discussionForumHome",
EMPTY_ATTR);

      //Create the message elements
      AttributesImpl attribute = new AttributesImpl();
      attribute.addAttribute("", "", "id", "", "1");
      attribute.addAttribute("", "", "name", "", "Java Programming");
      contentHandler.startElement("", "", "messageBoard", attribute);
      contentHandler.endElement("", "", "messageBoard");

      attribute = new AttributesImpl();
      attribute.addAttribute("", "", "id", "", "2");
      attribute.addAttribute("", "", "name", "", "XML Programming");
      contentHandler.startElement("", "", "messageBoard", attribute);
      contentHandler.endElement("", "", "messageBoard");

      attribute = new AttributesImpl();
      attribute.addAttribute("", "", "id", "", "3");
      attribute.addAttribute("", "", "name", "", "XSLT Questions");
      contentHandler.startElement("", "", "messageBoard", attribute);
      contentHandler.endElement("", "", "messageBoard");

      contentHandler.endElement("","", "discussionForumHome");

      //End the document
      contentHandler.endDocument();
}



Again, very simple hard-coded SAX events.

Below is the code I use to do the parsing and stream the results to the
browser.  Note that the line that tries to set the XSL style sheet is
commented out; for now I just want to stream the XML back to the browser to
see what the XML reader code is producing.  Also note that
AccountSummaryXMLReader is the name of the class that implements XMLReader:


===========================
Listing 3
===========================
      try {
            TransformerFactory transFact = TransformerFactory.newInstance
();
            if (transFact.getFeature(SAXTransformerFactory.FEATURE)) {
                  SAXTransformerFactory saxTransFact =
                              (SAXTransformerFactory) transFact;
                  TransformerHandler transHand = null;

                  //transHand = saxTransFact.newTransformerHandler(
                        //new StreamSource(new File("C:
\\www\\accountaccessweb\\LMR\\xsl\\discussionForumHome.xslt")));
                  transHand = saxTransFact.newTransformerHandler();

                  //Set the destination
                  response.setContentType("text/xml");
                  transHand.setResult(new
StreamResult(response.getOutputStream()));

                  //Create the XMLReader and attach the content handler
                  XMLReader xmlReader = new AccountSummaryXMLReader();
                  xmlReader.setContentHandler(transHand);

                  xmlReader.parse(new InputSource());

            } else {
                  System.err.println("SAXTransformerFactory is not
supported.");
                  System.exit(1);
            }

      }
      catch(Throwable t) {
            System.out.println(t);
            return;
      }


Since there is no style sheet specified, the raw XML gets sent to the
browser.  Here's the source of the XML that is sent to the browser:

===========================
Listing 4
===========================
<?xml version="1.0" encoding="UTF-8"?>
<discussionForumHome><messageBoard id="1" name="Java
Programming"/><messageBoard id="2" name="XML Programming"/><messageBoard id
="3" name="XSLT Questions"/></discussionForumHome>


Which, of course, is identical to the XML I show at the top of the message.
So far, so good.

Now, I want to apply the simple style sheet to produce HTML.  Here's what
the style sheet looks like: (discussionForumHome.xslt)

===========================
Listing 5
===========================
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="html"/>
      <xsl:template match="/">
            <html>
                  <head>
                        <title>Discussion Forum Home Page</title>
                  </head>
                  <body>
                        <h1>Discussion Forum Home Page</h1>
                        <h3>Please select a message board to view:</h3>
                        <ul>
                        <xsl:apply-templates select
="discussionForumHome/messageBoard"/>
                        </ul>
                  </body>
            </html>
      </xsl:template>
      <xsl:template match="messageBoard">
        <li><a href="viewForum?id={@id}"><xsl:value-of select="
@name"/></a></li>
</xsl:template>
</xsl:stylesheet>




OK, we're almost there.  In Listing 3, I uncomment the line that sets the
transformer handler to point to discussionForumHome.xslt, and comment the
line that just sets it to a new handler (yes, I remembered to do it  ; - )
).  This should cause the XSL stylesheet to be merged with the XML events
to produce HTML, which is sent to the browser.  Please note that when
trying to produce HTML, I change content type to "text/html".  When I do
this, this is the HTML sent to the browser:


===========================
Listing 6
===========================
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Discussion Forum Home Page</title>
</head>
<body>
<h1>Discussion Forum Home Page</h1>
<h3>Please select a message board to view:</h3>
<ul></ul>
</body>
</html>



As you can see, none of the XML has been merged with the style sheet.  To
verify that the style sheet wasn't the problem, I tweaked my code to use a
standard XMLReader, read the XML file from disk, and send the output to the
browser.  Below is the tweak (it tweaks Listing 3):

===========================
Listing 7
===========================
      XMLReader x = XMLReaderFactory.createXMLReader();
      x.setContentHandler(transHand);
      x.parse(new InputSource(new FileReader(new File("C:
\\www\\accountaccessweb\\LMR\\xsl\\discussionForumHome.xml"))));


And it produces this result, sent to the browser:


===========================
Listing 8
===========================
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Discussion Forum Home Page</title>
</head>
<body>
<h1>Discussion Forum Home Page</h1>
<h3>Please select a message board to view:</h3>
<ul>
<li>
<a href="viewForum?id=1">Java Programming</a>
</li>
<li>
<a href="viewForum?id=2">XML Programming</a>
</li>
<li>
<a href="viewForum?id=3">XSLT Questions</a>
</li>
</ul>
</body>
</html>



Which is obviously correct, because the XML file has been merged with the
XSL style sheet.

The question:  Why can't I get this to work using my custom XMLReader?  It
seems to producing the exact same XML that is in the file, but it isn't
being merged with the XSL style sheet.  I can't track down the problem,
because it doesn't seem to be an XMLReader problem, because it's producing
the right SAX events.  But I can't seem to blame the XSL style sheet, or
the style sheet processor, because using the static XML file produces the
correct result.

Can somebody please determine what I'm doing wrong??  Like I said at the
beginning, I'm trying to read database records and send them to the browser
as HTML.  I don't want to write the XML out to a temp file only to have to
read the XML right back again.

In  case it helps, I'm using Xalan 2.3.1


Thank you very much for your help!!!  I know this is a long message, but I
wanted to be as complete as possible.

-Ryan