Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 53 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
53
Dung lượng
517,05 KB
Nội dung
In both cases, you invoke a serializer by including a handler attribute in the xml- stylesheet processing instruction. The following is an example where the XSLT processor is invoked prior to the serializer: <?xml-stylesheet type=”text/xsl” href=”someStylesheet.xsl” serializer=”java:some.pkg.SomeSerializer”?> If you want the serializer to process the raw XSQL datagram, you can simply omit the href attribute: <?xml-stylesheet type=”text/xsl” serializer=”java:some.pkg.SomeSerializer”?> In most cases, you will want to run a stylesheet before handing the XML over to a serializer. This is especially true for serializers that utilize other technologies, such as SVG or FOP. FOP, for instance, expects its data to be in agreement with a certain schema. If you are writing your own custom serializer, you may find it easier to just process the raw datagram. However, this does make your work less reusable. What if you want to use your code outside of XSQL? You might have to transform the data to match the canonical datagram schema. Instead, you’ll probably want to create your own schema for your custom serializer. Creating PDFs with Apache FOP Many Web sites offer PDFs. They are better suited for printing and can be more pol- ished than HTML Web pages. You have complete control over fonts, formatting, and images. But the PDF file format is binary, making it tough to code to directly. This is where the Apache FOP project comes in. You can use it to create PDF documents on the fly. By using XSQL and Apache FOP together, you can create dynamic PDF documents based on your database data. This section covers the architecture of Apache FOP and how to use the XSQL FOP serializer. FOP Architecture FOP uses the second part of the XSL family: XSL-FO. You’re very familiar with XSLT, the first part. The aim of XSL-FO is quite different from XSLT. While XSLT is an XML application that gives you the ability to transform an XML document to some kind of output, XSL-FO is aimed at giving you great control over how the document 520 Chapter 19 looks. FOP is open source software that allows you to process and render XSL-FO documents. You can think of XSL-FO as an attempt to overcome the presentation shortcomings of HTML and CSS. For instance, how many times have you struggled to get your ele- ments positioned on the page just right? Once you get it right on one browser, you have to check other browsers. How many times have you printed a document and taken it with you to read, only to find that the printer had chopped off the last four words on the right-hand side? XSL-FO allows you to define exactly how items fit on a page and what the size and orientation of the page is. Assuming enough tool support, you could create a good-looking printed book by using XSL-FO. This isn’t really true with HTML and CSS. However, there isn’t a lot of client software out there that understands XSL-FO directly. Maybe at some point, all the Web browsers will be able to accept and render XSL-FO documents just as they can handle HTML documents today. For now, you use XSL-FO to create one of the following established formats that meets the same goals as XSL-FO: ■■ PDF: Adobe Portable Document Format ■■ PCL: Printer Control Language from HP ■■ PostScript ■■ SVG: Scalable Vector Graphics ■■ AWT: Java Abstract Window Toolkit ■■ MIF: Marker Interchange Format for Adobe FrameMaker You may be wondering, What does XSL-FO bring to the table? Why not just write one of these formats directly? First, you’d lose the benefits of a strong open standard. You’d also have to learn the intricacies of the underlying standard. Perhaps one the best benefits of XSL-FO is that you can easily use it in conjunction with XSLT stylesheets. You can transform an XSQL datagram in to an XSL-FO document. The XSQL FOP serializer hands it to FOP, which outputs the appropriate format. The archi- tecture appears in Figure 19.2. From the standpoint of the developer, you can consider that XSL-FO replaces HTML. Instead of writing an XSLT stylesheet that transforms the datagram in to HTML, you transform the datagram in to XSL-FO. Then, the serializer creates the out- put format. This is usually PDF. The XSQL FOP serializer that you’ll look at in the next section writes to PDF. However, if you need to write to one of the other standards you can easily write your own serializer. The details of XSL-FO aren’t covered in this book. Appendix A points to some resources online that can help you learn and use XSL-FO. Serializers 521 Figure 19.2 XSL-FO and FOP architecture. Using the XSQL FOP Serializer The XSQL FOP serializer comes with the XSQL distribution. You’ll need to do a little work before you can use it, though. First, you’ll need to download the release from Apache. Once that is installed, you need to set the classpath for your servlet engine so that it points to the correct jar files. From there, you should be able to verify your install by running the samples provided in the XSQL demos. The home page for FOP is http://xml.apache.org/fop. Before downloading a distribution, you should first check your XSQL release notes. They will specify the appropriate version of FOP to use with the XSQL FOP serializer. At the time of this writing, XSQL supports FOP 0.19.0. Once it is downloaded, you simply expand the dis- tribution file in to a convenient directory. Now you need to set up the classpath. If you are using the Oracle Apache server, you should add the following to your jserv.properties file: wrapper.classpath=c:\xsql\Fop-0.19.0-CVS\fop.jar wrapper.classpath=c:\xsql\Fop-0.19.0-CVS\lib\avalon-framework-cvs- 20020315.jar <ROWSET> <ROW> </ROW> </ROW> </ROW> </ROWSET> XSQL Datagram XSLT Processor XSLT Stylesheet xsl:fo Document PDF Document Client FOP Serializer Apache FOP 522 Chapter 19 wrapper.classpath=c:\xsql\Fop-0.19.0-CVS\lib\batik.jar wrapper.classpath=c:\xsql\Fop-0.19.0-CVS\lib\xalan-2.3.1.jar wrapper.classpath=c:\xsql\Fop-0.19.0-CVS\lib\xercesImpl-2.0.1.jar wrapper.classpath=c:\xsql\Fop-0.19.0-CVS\lib\xml-apis.jar This takes care of FOP. You also need to make sure that the XSQL FOP serializer itself is installed. Here is the line that you need: wrapper.classpath=C:\xsql\lib\xsqlserializers.jar There should be a nickname for the XSQL FOP serializer in the XSQLConfig.xml file. You’ll need to have the nickname in place for the samples to work correctly. You’ll find it in the serializerdefs element. This is what it looks like: <serializer> <name>FOP</name> <class>oracle.xml.xsql.serializers.XSQLFOPSerializer</class> </serializer> You should be ready to go. There should be an FOP directory underneath your demos. If you installed XSQL on a local Web server, you should be able to access the demo with http://localhost/xsql/fop/emptable.xsql. This produces the output shown in Figure 19.3. Figure 19.3 Demo PDF output. Serializers 523 Here’s a closer look at what is going on. The XSQL looks quite like what you’ve seen before, except that a serializer is specified: <?xml version=”1.0”?> <?xml-stylesheet type=”text/xsl” href=”emptablefo.xsl” serializer=”FOP”?> <xsql:query connection=”demo” xmlns:xsql=”urn:oracle-xsql”> SELECT ENAME, SAL FROM EMP ORDER BY SAL asc </xsql:query> The stylesheet looks quite a bit different, though: <?xml version=”1.0”?> <fo:root xmlns:fo=”http://www.w3.org/1999/XSL/Format” xsl:version=”1.0” xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”> <! defines the layout master > <fo:layout-master-set> <fo:simple-page-master master-name=”first” page-height=”29.7cm” page-width=”21cm” margin-top=”1cm” margin-bottom=”2cm” margin-left=”2.5cm” margin-right=”2.5cm”> <fo:region-body margin-top=”3cm”/> </fo:simple-page-master> </fo:layout-master-set> <! starts actual layout > <fo:page-sequence master-name=”first”> <fo:flow flow-name=”xsl-region-body”> <fo:block font-size=”24pt” font-family=”Garamond” line- height=”24pt” space-after.optimum=”3pt” font-weight=”bold” start- indent=”15pt”> Total of All Salaries is $<xsl:value-of select=”sum(/ROWSET/ROW/SAL)”/> </fo:block> <! Here starts the table > <fo:block border-width=”2pt”> <fo:table> <fo:table-column column-width=”4cm”/> <fo:table-column column-width=”4cm”/> <fo:table-body font-size=”10pt” font-family=”sans-serif”> <xsl:for-each select=”ROWSET/ROW”> <fo:table-row line-height=”12pt”> <fo:table-cell> <fo:block><xsl:value-of select=”ENAME”/></fo:block> 524 Chapter 19 </fo:table-cell> <fo:table-cell> <fo:block><xsl:value-of select=”SAL”/></fo:block> </fo:table-cell> </fo:table-row> </xsl:for-each> </fo:table-body> </fo:table> </fo:block> </fo:flow> </fo:page-sequence> </fo:root> The best way to get an idea as to what the serializer is doing is to look at the XML that the serializer processes. You can do this by simply commenting out the serializer attribute in the XSQL page. This yields a document like the following. The document here is an abbreviated version of the document used to produce the PDF in Figure 19.3; it includes only three of the rows. <?xml version=”1.0” ?> <fo:root xmlns:fo=”http://www.w3.org/1999/XSL/Format”> <fo:layout-master-set> <fo:simple-page-master master-name=”first” page-height=”29.7cm” page-width=”21cm” margin-top=”1cm” margin-bottom=”2cm” margin-left=”2.5cm” margin-right=”2.5cm”> <fo:region-body margin-top=”3cm” /> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-name=”first”> <fo:flow flow-name=”xsl-region-body”> <fo:block font-size=”24pt” font-family=”Garamond” line-height=”24pt” space-after.optimum=”3pt” font-weight=”bold” start-indent=”15pt”> Total of All Salaries is $14650 </fo:block> <fo:block border-width=”2pt”> <fo:table> <fo:table-column column-width=”4cm” /> <fo:table-column column-width=”4cm” /> <fo:table-body font-size=”10pt” font-family=”sans-serif”> <fo:table-row line-height=”12pt”> <fo:table-cell> <fo:block>SMITH</fo:block> </fo:table-cell> <fo:table-cell> Serializers 525 <fo:block>800</fo:block> </fo:table-cell> </fo:table-row> <fo:table-row line-height=”12pt”> <fo:table-cell> <fo:block>JAMES</fo:block> </fo:table-cell> <fo:table-cell> <fo:block>950</fo:block> </fo:table-cell> </fo:table-row> <fo:table-row line-height=”12pt”> <fo:table-cell> <fo:block>ALLEN</fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table> </fo:block> </fo:flow> </fo:page-sequence> </fo:root> It looks quite a bit similar to HTML, but note that fonts and margins are defined precisely. This is the beauty of XSL-FO—that you are able to describe exactly what you want. A full treatment of XSL-FO is beyond the scope of this book. For more information, you should visit http://xml.apache.org/fop/index.html. This Web site not only describes the Apache FOP project but also provides links to resources for XSL-FO and describes the parts of the XSL-FO specification that aren’t yet covered by Apache FOP. Creating Custom Serializers You can create your own custom serializers in a manner similar to that for action han- dlers. You implement an interface and then point to the Java class in the XSQL page. But instead of having multiple serializers in the same page you can only have one. This section walks you through the steps for writing serializers. You start by creating a sim- ple text serializer. This should give you a good idea of how to program serializers. The second section shows you how to write binary serializers. There isn’t a lot of difference between writing text and writing binary serializers. In both cases, your class has to implement the oracle.xml.xsql.XSQLDocument- Serializer interface. These basic steps are expected for both text and binary serializers: 1. Set the content type. 2. Write the output. You have to set the content type before writing any output. When outputting text, you can optionally specify a character encoding. You can write to either a stream or a writer, though you shouldn’t try to write to both. 526 Chapter 19 Now it’s time for some examples, starting with a simple text serializer. Text Serializers As discussed previously, there isn’t a lot that you can accomplish with a text serializer that you can’t handle with an XSLT stylesheet. But from a learning perspective, the text serializer can be easier to understand. Here is a simple text serializer that outputs the skeleton of an XML document as HTML. Only the names of the elements are written. import oracle.xml.xsql.XSQLPageRequest; import oracle.xml.xsql.XSQLDocumentSerializer; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.io.PrintWriter; public class SimpleTextSerializer implements XSQLDocumentSerializer { public void serialize(Document doc, XSQLPageRequest env) { String mimeType=”text/html”; String encoding=env.getPageEncoding(); if (encoding!=null && encoding.length()>0) { mimeType=mimeType+”;charset=”+encoding; } env.setContentType(mimeType); PrintWriter out=env.getWriter(); The content type is set in the preceding lines. If a page encoding is specified in the XSQL page, it will be attached to the mime-type. You get the PrintWriter from the XSQLPageRequest object. Optionally, you could call getOutputStream() and write to a stream instead. However, you should try to write only to one or the other. The remainder of the serialize() method sets up the beginning and ending HTML and calls the displayElement() method. Element docElem=doc.getDocumentElement(); out.println(“<html>”); out.println(“<head><title>”+docElem.getTagName()+”</title></head>”); out.println(“<body><H1>Document: “+docElem.getTagName()+”</H1>”); out.println(“<table>”); displayElement(doc.getDocumentElement(),out,0); out.println(“</table>”); } Serializers 527 The displayElement() method is a recursive element that descends the docu- ment. The name for each element is printed, and then the method is called on each child of the elem element. The level argument represents the level in the tree at which the method is found. It is used to set the indentations properly. private void displayElement(Element elem, PrintWriter out, int level) { out.println(“<tr><td>”); out.println(getSpaces(level)+”<b>”+elem.getTagName()+”</b>”); out.println(“</td><tr>”); NodeList list=elem.getChildNodes(); for (int i=0;i<list.getLength();i++) { Node n=list.item(i); if (n.getNodeType()==Node.ELEMENT_NODE) { displayElement((Element)n,out,level+1); } } } The final method in the serializer is used to set the spacing. Three spaces are set for each level in depth. private String getSpaces(int num) { String s=””; for (int i=0;i<num*3;i++) { s=s+” ”; } return s; } } Now you need to invoke your serializer. The following XSQL page will apply only the serializer to the XSQL datagram. Since no stylesheet is specified, no XSLT transfor- mation will be performed prior to invoking the serializer. <?xml version=”1.0”?> <?xml-stylesheet serializer=”java:SimpleTextSerializer”?> <page xmlns:xsql=”urn:oracle-xsql” connection=”demo”> <xsql:query> 528 Chapter 19 select ename, job, sal from emp where deptno=20 order by sal </xsql:query> </page> This produces the output shown in Figure 19.4. For this example, you can see that the elements for the raw datagram are listed. You can also apply a serializer to the results of an XSLT transformation. The follow- ing XSQL page transforms the datagram with a stylesheet. The serializer is then called to process the results of that transformation. <?xml version=”1.0”?> <?xml-stylesheet type=”text/xsl” href=”emp-serializer.xsl” serializer=”java:SimpleTextSerializer”?> <page xmlns:xsql=”urn:oracle-xsql” connection=”demo”> <xsql:query> SELECT ename, job, sal FROM emp WHERE deptno=20 ORDER BY sal </xsql:query> </page> Figure 19.4 SimpleTextSerializer output. Serializers 529 [...]... an SQL statement as input import oracle. xml .xsql. XSQLPageRequest; import oracle. xml .xsql. XSQLDocumentSerializer; import oracle. xml.parser.v2.XMLElement; import java. io.OutputStream; import java. io.PrintWriter; import java. io.InputStream; import org.w3c.dom.Document; import oracle. jdbc.driver.OracleResultSet; import oracle. sql. BLOB; Serializers import import import import java .sql. ResultSet; java .sql. Statement;... 503–505 XSU classes and, 502–503 actions, described, 66 See also action handlers actions (listed by name) xsql: action, 89, 480, 483, 485, 496 xsql: delete-request, 92–93, 121–122, 467 xsql: dml, 82–83, 122–123, 129, 246, 376 xsql: include-owa, 83–84, 263–270, 376, 393–394, 400 xsql: include-request-params, 82, 84–85, 100 102 , 105 xsql: include -xsql, 89–90, 397 xsql: insert-param, 93–94, 128–129 xsql: insert-request,... /batik/ SQLJ and Java- Stored Procedures This book showed you how to create stored procedures using PL /SQL You can also create stored procedures using Java This is known as SQLJ You find the Oracle guide to SQLJ at http://otn .oracle. com/tech /java/ sqlj_jdbc/pdf/a96655.pdf SQLJ is implemented with a precompiler It translates statements in your Java source code to calls to the SQLJ APIs These calls sit on top... blue=”200”/> CLARK< /text> Serializers KING< /text> ... wondering which is better, PL /SQL or Java stored procedures? Java stored procedures take up a little more memory and can underperform PL /SQL when there are a lot of SQL statements Java stored procedures have the disadvantage that statements have to be translated to SQL, whereas PL /SQL supports SQL natively At the same time, Java is a much more predominant language than PL /SQL and has a richer native API... section and, 234–235 headers for, 228 XSLT and, 281 boolean expressions conditional logic and, 307, 310 described, 307 variables and, 334 XPath and, 344–345 XSLT and, 307–308, 310, 334, 344–345, 363–364 boolean function, 308 br element, 279, 283 browsers cookies and, 106 108 Lynx, 96 Netscape Navigator, 96 POST method and, 125 serializers and, 518 stylesheet choices based on the type of, 96 Web services and, ... 93–94, 128–129 xsql: insert-request, 90–91, 119–120, 124, 128–129 xsql: ref-cursor-function, 83, 243, 250–251, 257 xsql: set-cookie, 87–88, 108 , 418 xsql: set-page-param, 85–86, 104 xsql: set-session-param, 86–87 xsql: set-stylesheet-param, 88–89 553 554 Index actions (listed by name) (continued) xsql: update-request, 91–92, 120–121, 467 See also xsql: query action Active Server Pages See ASP ActiveX objects (Microsoft),... Scalable Vector Graphics (SVG) Scalable Vector Graphics (SVG) creates an image based on an XML document XSQL can easily produce SVG documents and thus gives you an easy way to create images based on dynamic data derived from your database You simply write an XSLT stylesheet that converts the XSQL datagram to an SVG document An example of how to do this is included in the XSQL distribution from Oracle SVG... database that you wish to push to the client, you will have to use a serializer both to write it and to fetch it from the database From our earlier discussions, it’s obvious that you have to use a serializer to deliver binary data from XSQL But in contrast to text data, you can’t really provide binary data as input to a serializer The serializer takes XML as input, and XML is a text format You could... If you are using XSQL in conjunction with Java either by embedding XSQL in your code or writing custom action handlers or serializers—you can find the API documentation available in javadoc format at http://otn .oracle. com/docs /tech/xml/xdk _java/ doc_library/Production9i/index.html The Oracle XDK and the Oracle XML DB are considered separate by Oracle If you want information about storing XML in the . file system and writes it out. In this example, the XML input is ignored. import oracle. xml .xsql. XSQLPageRequest; import oracle. xml .xsql. XSQLDocumentSerializer; import java. io.OutputStream; import java. io.BufferedOutputStream; import. org.w3c.dom.Document; import oracle. jdbc.driver.OracleResultSet; import oracle. sql. BLOB; 534 Chapter 19 import java .sql. ResultSet; import java .sql. Statement; import java .sql. DriverManager; import java .sql. Connection; public. serializer= java: SimpleBinarySerializer”?> < ;xsql: query xmlns :xsql= ”urn :oracle- xsql connection=”demo”> SELECT file-name, content- type FROM binary_table WHERE id={@some-param} < /xsql: query> The