You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-users@xmlgraphics.apache.org by Jen Liu <da...@yahoo.com> on 2002/07/17 20:42:57 UTC
SAX Parser � XML
I am trying to create XML containing data retrieved from the database but not write into the disk then pass it with my XSL-FO into FOP to generate PDF file. The following is the code I have and please advise if the code looks all right and how can I view the content written in XML string and which variable (string) I should pass as the equivalence as an actual XML file?
Thanks.
My Code:
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.sql.*;
import java.io.*;
public class DatabaseFilter extends XMLFilterImpl {
public static void main(String[] args) throws SQLException {
new DatabaseFilter();
}
private Connection connection;
// The string passed to the constructor must be a JDBC URL that contains all necessary
// information for connecting to the database such as host, port, username, password, and database name.
// For example, jdbc:mysql://host:port]/dbname?user=username&password=pass
// The driver should have been loaded before this method is called dddsa
public DatabaseFilter() throws SQLException {
// Load the Oracle JDBC Driver
try{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
} catch(Exception e){
}
String connURL = "jdbc:oracle:thin:@10.17.182.6:1521:IASWDEV1";
String connUser = "data";
String connPwd = "data";
String selectQuery = "SELECT * FROM apps";
connection = DriverManager.getConnection(connURL, connUser, connPwd);
try {
parse(selectQuery) ;
} catch(Exception e){
}
}
public void parse(String selectQuery) throws SAXException, IOException {
try {
Statement statement = connection.createStatement();
ResultSet data = statement.executeQuery(selectQuery);
ResultSetMetaData metadata = data.getMetaData();
int numFields = metadata.getColumnCount();
Attributes emptyAttributes = new AttributesImpl();
startElement("", "table", "table", emptyAttributes);
while (data.next()) {
startElement("", "record", "record", emptyAttributes);
for (int field = 1; field <= numFields; field++) {
AttributesImpl fieldAtts = new AttributesImpl();
int type = metadata.getColumnType(field);
String typeName = getSchemaType(type);
fieldAtts.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", "xsi:type", "NMTOKEN", typeName);
String name = metadata.getColumnName(field);
fieldAtts.addAttribute("", "name", "name", "NMTOKEN", name);
// Convert nulls to empty elements with xsi:nil="true"
Object value = data.getObject(field);
file://System.out.println("Column Value = " + data.getObject(field));
if (value == null) { // null value in database
fieldAtts.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi:nil", "NMTOKEN", "true");
startElement("", "field", "field", fieldAtts);
endElement("", "field", "field");
}
else { // non-null value
startElement("", "field", "field", fieldAtts);
convertToXML(data, field, type);
endElement("", "field", "field");
}
}
endElement("", "record", "record");
}
endElement("", "table", "table");
file://System.out.println(fieldAtts.toString());
System.out.println("jenny" + emptyAttributes.toString());
statement.close();
}
catch (SQLException e) { // convert exception type
throw new SAXException(e);
}
}
// I want the XML document to store values in the standard W3C XML Schema Language forms.
// This requires certain conversions depending on the type of the data
private void convertToXML(ResultSet data, int field, int type) throws SQLException, SAXException {
switch (type) {
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
hexEncode(data.getBinaryStream(field));
break;
case Types.BLOB:
Blob blob = data.getBlob(field);
hexEncode(blob.getBinaryStream());
break;
// String types may contain C0 control characters that are not legal in XML. How should this be handled????
case Types.CLOB:
Clob clob = data.getClob(field);
Reader r = clob.getCharacterStream();
char[] text = new char[1024];
int numRead;
try {
while ((numRead = r.read(text, 0, 1024)) != -1) {
characters(text, 0, numRead);
}
}
catch (IOException e) {
throw new SAXException("Read from CLOB failed");
}
break;
case Types.ARRAY:
Array array = data.getArray(field);
writeArray(array);
break;
default: // All other types can be handled as strings
Object o = data.getObject(field);
if (o == null) return;
String s = o.toString();
char[] value = s.toCharArray();
characters(value, 0, value.length);
}
}
private void hexEncode(InputStream in)
throws SQLException, SAXException {
try {
int octet;
while ((octet = in.read()) != -1) {
StringWriter out = new StringWriter(2);
if (octet < 16) out.write('0');
out.write(Integer.toHexString(octet));
char[] text = out.toString().toCharArray();
characters(text, 0, 2);
}
}
catch (IOException e) {
throw new SAXException(e);
}
}
private void writeArray(Array array)
throws SQLException, SAXException {
ResultSet data = array.getResultSet();
int type = array.getBaseType();
String typeName = getSchemaType(type);
while (data.next()) {
AttributesImpl fieldAtts = new AttributesImpl();
fieldAtts.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", "xsi:type", "NMTOKEN", typeName);
startElement("", "component", "component", fieldAtts);
convertToXML(data, 2, type);
endElement("", "component", "component");
}
}
public static String getSchemaType(int type) {
switch (type) {
case Types.ARRAY: return "array";
case Types.BIGINT: return "xsd:long";
case Types.BINARY: return "xsd:hexBinary";
case Types.BIT: return "xsd:boolean";
case Types.BLOB: return "xsd:hexBinary";
case Types.CHAR: return "xsd:string";
case Types.CLOB: return "xsd:string";
case Types.DATE: return "xsd:date";
case Types.DECIMAL: return "xsd:decimal";
case Types.DOUBLE: return "xsd:double";
case Types.FLOAT: return "xsd:decimal";
case Types.INTEGER: return "xsd:int";
case Types.JAVA_OBJECT: return "xsd:string";
case Types.LONGVARBINARY: return "xsd:hexBinary";
case Types.LONGVARCHAR: return "xsd:string";
case Types.NUMERIC: return "xsd:decimal";
case Types.REAL: return "xsd:float";
case Types.REF: return "xsd:IDREF";
case Types.SMALLINT: return "xsd:short";
case Types.STRUCT: return "struct";
case Types.TIME: return "xsd:time";
case Types.TIMESTAMP: return "xsd:dateTime";
case Types.TINYINT: return "xsd:byte";
case Types.VARBINARY: return "xsd:hexBinary";
// most general type
default: return "xsd:string";
}
}
// Warn clients that this filter does not receive its events from another XML parser
public void setParent(XMLReader parent) throws UnsupportedOperationException {
throw new UnsupportedOperationException("A DatabaseFilter reads from an underlying SQL database;" + " not an underlying XML parser");
}
}
---------------------------------
Do You Yahoo!?
Yahoo! Autos - Get free new car price quotes
Re: SAX Parser - XML
Posted by Denis Balazuc <De...@trader.com>.
As for FOP-ying your resulting XML (which should be some XSL:FO code), here's the code I use :
//FO->PDF
String foString = "?"//Your FO string;
Driver driver = new org.apache.fop.apps.Driver();
driver.setLogger(new ConsoleLogger());
driver.setRenderer(Driver.RENDER_PDF);
driver.setInputSource(new InputSource(new StringReader(foString )));
driver.setOutputStream(System.out);
driver.run();
//System.out contains the resulting PDF
You can change the setInputSource() to take whatever you want in input (generally an URL or a Reader)
and the setOutputStream() to direct the output to a file, to a servlet outputstream, etc.
It might not be the more efficient way to do this, but it works fine for me.
>From what I read, you still need to transform your XML into a XSL:FO file before being able to render it as PDF.
Assuming you have a "transform.xsl" file that does such an XML->XSL:FO transformation, this is how you do this :
//Get the Templates object from the XSL file ("transform.xsl")
InputStream in = (new URL("transform.xsl")).openStream();
Source source = new StreamSource(in);
Templates templates =TransformerFactory.newInstance().newTemplates(source);
String xmlString = "?";//what you have extracted from the DB and parsed
StringReader reader = new StringReader(xmlString); //make it a stream usable for a Source object
StringWriter writer = new StringWriter(); //will be used to get the result of XLS transformation
templates.newTransformer().transform(new StreamSource(reader), new StreamResult(writer));
writer.close();
String foString = writer.toString(); //contains your XSL transformed XML now usable for FOP
Basically, you use the default TransformerFactory (see javax.xml.transform.*) for getting Templates instances that represent an XSL file.
Those Templates provides you with Transformer instances that are able to process a Source into a Result according to your XSL and the XML you use for the Source.
NB : you may want to cache the Templates instances but don't cache Transformer instances if you are in a multi-threaded environment.
You can safely cache TransformerFactory instances provided you don't want to dynamically change the implementation of it at runtime.
Hope this helps
Denis Balazuc
----- Original Message -----
From: Jen Liu
To: fop-user@xml.apache.org
Sent: Wednesday, July 17, 2002 2:42 PM
Subject: SAX Parser - XML
I am trying to create XML containing data retrieved from the database but not write into the disk then pass it with my XSL-FO into FOP to generate PDF file. The following is the code I have and please advise if the code looks all right and how can I view the content written in XML string and which variable (string) I should pass as the equivalence as an actual XML file?
Thanks.
My Code:
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.sql.*;
import java.io.*;
public class DatabaseFilter extends XMLFilterImpl {
public static void main(String[] args) throws SQLException {
new DatabaseFilter();
}
private Connection connection;
// The string passed to the constructor must be a JDBC URL that contains all necessary
// information for connecting to the database such as host, port, username, password, and database name.
// For example, jdbc:mysql://host:port]/dbname?user=username&password=pass
// The driver should have been loaded before this method is called dddsa
public DatabaseFilter() throws SQLException {
// Load the Oracle JDBC Driver
try{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
} catch(Exception e){
}
String connURL = "jdbc:oracle:thin:@10.17.182.6:1521:IASWDEV1";
String connUser = "data";
String connPwd = "data";
String selectQuery = "SELECT * FROM apps";
connection = DriverManager.getConnection(connURL, connUser, connPwd);
try {
parse(selectQuery) ;
} catch(Exception e){
}
}
public void parse(String selectQuery) throws SAXException, IOException {
try {
Statement statement = connection.createStatement();
ResultSet data = statement.executeQuery(selectQuery);
ResultSetMetaData metadata = data.getMetaData();
int numFields = metadata.getColumnCount();
Attributes emptyAttributes = new AttributesImpl();
startElement("", "table", "table", emptyAttributes);
while (data.next()) {
startElement("", "record", "record", emptyAttributes);
for (int field = 1; field <= numFields; field++) {
AttributesImpl fieldAtts = new AttributesImpl();
int type = metadata.getColumnType(field);
String typeName = getSchemaType(type);
fieldAtts.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", "xsi:type", "NMTOKEN", typeName);
String name = metadata.getColumnName(field);
fieldAtts.addAttribute("", "name", "name", "NMTOKEN", name);
// Convert nulls to empty elements with xsi:nil="true"
Object value = data.getObject(field);
file://System.out.println("Column Value = " + data.getObject(field));
if (value == null) { // null value in database
fieldAtts.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi:nil", "NMTOKEN", "true");
startElement("", "field", "field", fieldAtts);
endElement("", "field", "field");
}
else { // non-null value
startElement("", "field", "field", fieldAtts);
convertToXML(data, field, type);
endElement("", "field", "field");
}
}
endElement("", "record", "record");
}
endElement("", "table", "table");
file://System.out.println(fieldAtts.toString());
System.out.println("jenny" + emptyAttributes.toString());
statement.close();
}
catch (SQLException e) { // convert exception type
throw new SAXException(e);
}
}
// I want the XML document to store values in the standard W3C XML Schema Language forms.
// This requires certain conversions depending on the type of the data
private void convertToXML(ResultSet data, int field, int type) throws SQLException, SAXException {
switch (type) {
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
hexEncode(data.getBinaryStream(field));
break;
case Types.BLOB:
Blob blob = data.getBlob(field);
hexEncode(blob.getBinaryStream());
break;
// String types may contain C0 control characters that are not legal in XML. How should this be handled????
case Types.CLOB:
Clob clob = data.getClob(field);
Reader r = clob.getCharacterStream();
char[] text = new char[1024];
int numRead;
try {
while ((numRead = r.read(text, 0, 1024)) != -1) {
characters(text, 0, numRead);
}
}
catch (IOException e) {
throw new SAXException("Read from CLOB failed");
}
break;
case Types.ARRAY:
Array array = data.getArray(field);
writeArray(array);
break;
default: // All other types can be handled as strings
Object o = data.getObject(field);
if (o == null) return;
String s = o.toString();
char[] value = s.toCharArray();
characters(value, 0, value.length);
}
}
private void hexEncode(InputStream in)
throws SQLException, SAXException {
try {
int octet;
while ((octet = in.read()) != -1) {
StringWriter out = new StringWriter(2);
if (octet < 16) out.write('0');
out.write(Integer.toHexString(octet));
char[] text = out.toString().toCharArray();
characters(text, 0, 2);
}
}
catch (IOException e) {
throw new SAXException(e);
}
}
private void writeArray(Array array)
throws SQLException, SAXException {
ResultSet data = array.getResultSet();
int type = array.getBaseType();
String typeName = getSchemaType(type);
while (data.next()) {
AttributesImpl fieldAtts = new AttributesImpl();
fieldAtts.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", "xsi:type", "NMTOKEN", typeName);
startElement("", "component", "component", fieldAtts);
convertToXML(data, 2, type);
endElement("", "component", "component");
}
}
public static String getSchemaType(int type) {
switch (type) {
case Types.ARRAY: return "array";
case Types.BIGINT: return "xsd:long";
case Types.BINARY: return "xsd:hexBinary";
case Types.BIT: return "xsd:boolean";
case Types.BLOB: return "xsd:hexBinary";
case Types.CHAR: return "xsd:string";
case Types.CLOB: return "xsd:string";
case Types.DATE: return "xsd:date";
case Types.DECIMAL: return "xsd:decimal";
case Types.DOUBLE: return "xsd:double";
case Types.FLOAT: return "xsd:decimal";
case Types.INTEGER: return "xsd:int";
case Types.JAVA_OBJECT: return "xsd:string";
case Types.LONGVARBINARY: return "xsd:hexBinary";
case Types.LONGVARCHAR: return "xsd:string";
case Types.NUMERIC: return "xsd:decimal";
case Types.REAL: return "xsd:float";
case Types.REF: return "xsd:IDREF";
case Types.SMALLINT: return "xsd:short";
case Types.STRUCT: return "struct";
case Types.TIME: return "xsd:time";
case Types.TIMESTAMP: return "xsd:dateTime";
case Types.TINYINT: return "xsd:byte";
case Types.VARBINARY: return "xsd:hexBinary";
// most general type
default: return "xsd:string";
}
}
// Warn clients that this filter does not receive its events from another XML parser
public void setParent(XMLReader parent) throws UnsupportedOperationException {
throw new UnsupportedOperationException("A DatabaseFilter reads from an underlying SQL database;" + " not an underlying XML parser");
}
}
------------------------------------------------------------------------------
Do You Yahoo!?
Yahoo! Autos - Get free new car price quotes