麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

使用DOM和XSL來格式化由Java提取的數據

2019-11-18 14:29:15
字體:
來源:轉載
供稿:網友

  java可從任何JDBC兼容數據庫提取數據,將數據轉換成一個DOM對象,然后用XSL將數據格式化成需要的形式。在上一篇文章中,我們演示了如何從數據庫中程序化地提取數據。現在,讓我們討論如何生成DOM對象,并用一個XSL樣式表來格式化數據。這樣一來,最終的輸出就可用于任何應用程序,只要你為它們提供需要的輸入。



生成DOM文檔


Java的最新版本支持JAXP xml處理,并實現了由萬維網協會(W3C)定義的DOM API。使用這些相容于JAXP的版本,只需3行代碼即可創建一個DOM文檔對象,其中用到了JAXP factory和builder方法:


DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();

我們創建一個名為resultset的根元素,并把它添加到文檔對象中


Element root = document.createElement("resultset");
document.appendChild(root);

resultset游標遍歷結果集時,在根元素中添加包含行數據的一個新元素:


Element nextRow = document.createElement("row");

列計數必須從ResultSetMetaData對象中讀取;在本項目的數據庫數據提取階段,它必須是已經定義好的:

int columnCount = rsmd.getColumnCount();

列名要用for循環來檢索;針對每個列名,都添加一個name節點,它帶有一個子TextNode,其中包含用于一個names元素的名值:


String[] columnNames = new String[columnCount];
Element names = document.createElement("names");
for (int i = 0; i 〈 columnCount; i++){
/* the first column is 1, the second is 2, ... */
columnNames[i] = rsmd.getColumnName(i + 1);
Element nextNameNode = document.createElement("name");
Text nextName = document.createTextNode(columnNames[i]);
nextNameNode.appendChild(nextName);
names.appendChild(nextNameNode);
}

列索引從1開始,而非從0開始。讀取每個數據行時,列值都在一個for循環中作為字符串來泛化地檢索,這個for循環將讀取每一個列值:



/* Move the cursor through the data one row at a time. */
while(resultSet.next()){
/* Create an Element node for each row of data. */
Element nextRow = document.createElement("row");
if (debug) System.out.for (int i = 0; i 〈 columnCount; i++){
/* Create an Element node for each column value. */
Element nextNode = document.createElement(columnNames[i]);
/* the first column is 1, the second is 2, ... */
/* getString() will retrieve any of the basic SQL types*/
Text text = document.createTextNode(resultSet.getString(i + 1));
nextNode.appendChild(text);
nextRow.appendChild(nextNode);
}
root.appendChild(nextRow);
}

所有數據都轉換到一個DOM文檔對象中之后,連接就可關閉。DataBaseHandler永遠不需要進行文件操作。XML文檔是在內存中創建的。
一個具體的DataBaseHandler對象


使用少數幾行代碼,即可構造一個泛化的DefaultDataBaseHandler:



public class DefaultDataBaseHandler extends AbstractDataBaseHandler{

public DefaultDataBaseHandler(String urlString, String userName,
String pass
Word, String driverName){

setUrlString(urlString);
setUserName(userName);
setPassword(password);
setDriverName(driverName);
}
}

OracleDataBase處理程序稍微有點兒復雜:

public class OracleDataBaseHandler extends AbstractDataBaseHandler{

private String thinOraclePrefix = "jdbc:oracle:thin:@";
private String urlString;
private String userName;
private String password;
private String driverName = "oracle.jdbc.OracleDriver";
private String host;
private String port;
private String sid;

public OracleDataBaseHandler(String host, String sid,
String userName, String password){

this.host = host;
this.sid = sid;
/* a valid url connection string format is: "host:port:sid" */
setUrlString(thinOraclePrefix + host + ":1521:" + sid);
setUserName(userName);
setPassword(password);
}

public OracleDataBaseHandler(String host, String port, String sid,
String userName, String password){

this.host = host;
this.sid = sid;
this.port = port;
/* a valid url connection string format is: "host:port:sid" */
setUrlString(thinOraclePrefix + host + ":" + port + ":" + sid);
setUserName(userName);
setPassword(password);
}
}

ODBCDataBaseHandler區別不大,只是它處理的是數據源名稱(DSN),而非主機名稱、端口和SID。之所以要使用與Oracle數據庫有關的主機名稱、端口號和SID,是因為我們處理的是一個數據庫服務器,而不是一個數據庫文件。但是,Microsoft access關系數據庫要使用.mdb文件:

public class ODBCDataBaseHandler extends AbstractDataBaseHandler{

private String urlString;
private String userName;
private String password;
private String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
private String dsn;
private String odbcPrefix = "jdbc:odbc:";
public ODBCDataBaseHandler(String dsn, String userName, String password){
/* a valid url connection string format is: "jdbc:odbc:dsn" */
this.dsn = dsn;
setUrlString(odbcPrefix + dsn);
setUserName(userName);
setPassword(password);
setDriverName(driverName);
}
}

要了解訪問一種特定數據庫的細節,請查閱產品文檔。你需要用另一個類來調用一個具體的DataBaseHandler,并進行XSL轉換,從而將數據庫結果轉換成一種有用的替代輸出類型。
SQLMapper

SQLMapper類用一個DataBaseHandler類來完成它的數據庫工作,并用一個映射方法將文檔對象轉換成需要的輸出類型。映射方法返回一個字符串,因為原來就假定輸出由字符數據構成。另外,也可以使用一個StringBuffer。

SQLMapper需要一個SQL查詢字符串、一個輸出類型集以及一個用于執行具體工作的DataBaseHandler。它們用set方法來初始化,并用get方法來檢索:




if ((getSQL() != null)
&& (getSQL().length() 〉 0)
&& (getOutputType() != null)
&& (isValidOutputType(getOutputType()))
&& (getDataBaseHandler() != null)){
Document document = dataBaseHandler.getDocument(getSQL());

為了轉換成需要的輸出,需要在set方法中指定一個XSL樣式表。我們創建了一個Transformer對象,它只提供一個私有getTransformer方法。該方法可獲取一個默認樣式表或者指定的樣式表。如有必要,可使用Java的TransformerFactory方法來生成一個樣式表:



TransformerFactorytransformerfactory = TransformerFactory.newInstance();
transformer = transformerfactory.newTransformer(getStylesheet());

同樣只需要幾行Java代碼就可完成轉換:


Transformer transformer = getTransformer();
StringWritersw = new StringWriter();
StreamResult result = new StreamResult(sw);
if (transformer != null) {
transformer.transform(new DOMSource(document.getDocumentElement()), result);
output = sw.toString();
System.err.println("output: " + output);
}else{
System.err.println("No Transformer");
}

Transformer對象需要一個DOMSource對象。為了獲得這個對象,我們向Transformer的構造函數傳遞一個DOM文檔的根元素。

最后要由實現者設計自己的XSL樣式表。也可選用一些默認樣式表,以便將原始數據轉換成Html或者XML。下面是一個泛化的XSL樣式表,它能使用所謂的“標識轉換”(identity transformation)技術,將生成的數據轉換成一個XML文檔,并確保輸出內容相容于UTF-8標準,并具有良好的可讀性。

〈?xml version="1.0" encoding="UTF-8"?〉
〈xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"〉
〈xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" /〉
〈xsl:template match="@*node()"〉
〈xsl:copy〉
〈xsl:apply-templates select="@*node()"/〉
〈/xsl:copy〉
〈/xsl:template〉
〈/xsl:stylesheet〉


下面是一個泛化的XSL樣式表,它能將生成的數據轉換成一個HTML表格:




〈?xml version="1.0" encoding="UTF-8"?〉
〈xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"〉
〈xsl:output method="html" indent="yes" /〉

〈xsl:template match="resultset"〉
〈h2 align="center"〉Default HTML Transform Result〈/h2〉
〈table border="1" align="center"〉〈xsl:apply-templates/〉〈/table〉
〈/xsl:template〉
〈xsl:template match="names"〉
〈tr〉〈xsl:apply-templates/〉〈/tr〉
〈/xsl:template〉
〈xsl:template match="name"〉
〈td〉〈xsl:apply-templates/〉〈/td〉
〈/xsl:template〉
〈xsl:template match="row"〉
〈tr〉〈xsl:apply-templates/〉〈/tr〉
〈/xsl:template〉
〈xsl:template match="*"〉
〈td〉〈xsl:apply-templates/〉〈/td〉
〈/xsl:template〉

〈/xsl:stylesheet〉

下面是一個泛化的XSL樣式表,它將生成的數據轉換成一個WML(無線標記語言)表格:


〈?xml version="1.0" encoding="UTF-8"?〉
〈xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"〉
〈xsl:output method="html" indent="yes" /〉
〈xsl:template match="resultset"〉
〈wml〉
〈card id="index" title="Default WML Transform Result"〉
〈xsl:apply-templates/〉〈/card〉
〈/wml〉
〈/xsl:template〉
〈xsl:template match="names"〉
Names: 〈xsl:apply-templates/〉
〈/xsl:template〉
〈xsl:template match="name"〉
〈i〉〈xsl:apply-templates/〉〈/i〉
〈/xsl:template〉
〈xsl:template match="row"〉
〈card〉〈xsl:apply-templates/〉〈/card〉
〈/xsl:template〉
〈xsl:template match="*"〉
〈i〉〈xsl:apply-templates/〉〈/i〉
〈/xsl:template〉

〈/xsl:stylesheet〉

下面是一個泛化的XSL樣式表,它將生成的數據轉換成以逗號分隔的一個表格(CSV表格),它可直接用Excel讀取:



〈?xml version="1.0" encoding="UTF-8"?〉
〈xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"〉
〈xsl:output method="text" indent="yes"/〉
〈xsl:template match="names"〉
〈xsl:for-each select="*"〉
〈xsl:if test="position() != last()"〉〈xsl:value-of select="."/〉,〈/xsl:if〉
〈xsl:if test="position() = last()"〉〈xsl:value-of select="."/〉〈/xsl:if〉
〈/xsl:for-each〉
〈/xsl:template〉
〈xsl:template match="row"〉
〈xsl:for-each select="*"〉
〈xsl:if test="position() != last()"〉〈xsl:value-of select="."/〉,〈/xsl:if〉
〈xsl:if test="position() = last()"〉〈xsl:value-of select="."/〉〈/xsl:if〉
〈/xsl:for-each〉
〈/xsl:template〉
〈/xsl:stylesheet〉

運用SQLMapper的一些思路


后端數據庫可以使用一個表來定義網頁用戶界面的表單元素。在一個jsp頁中,只需幾行代碼即可檢索這個表。你的Web服務器也許安裝了一個Oracle數據庫,但是沒有前端圖形用戶界面。現在就可以定義一個GUI的元素,讓數據庫正式工作起來:


〈%@ page language="java" contentType="text/html" import="sqlmapper.*, mywebapp.* %〉
〈%@ page errorPage="errorPage.jsp" %〉
〈html〉
〈!-- getUserArea.jsp executed on 〈%= (new java.util.Date()) %〉 --〉
〈!-- @Author: Charles Bell --〉
〈!-- @Version: April 22, 2003 --〉
〈head〉
〈title〉Your company name - 〈%= dynamicTitle %〉〈/title〉
〈/head〉
〈body background="〈%= dynamicBackgroundImageFileName%〉"〉
〈%
WebAppUtilitymyWebAppUtility = new WebAppUtility();
String host = myWebAppUtility.getDatabaseHost();
String sid = myWebAppUtility.getDatabaseSID();
String userName = (String) session.getAttribute("validatedUserName");;
String password = myWebAppUtility.getDatabasePassord();
SQLMapper mapper = new SQLMapper();
DataBaseHandler dataBaseHandler=
new OracleDataBaseHandler(host, sid, userName, password);

mapper.setSQL("select * from FormDataElements");
mapper.setOutputType("html");
mapper.setDataBaseHandler(dataBaseHandler);
mapper.setXSLTranformStyleSheet("stylesheets/formdata.xsl");
out(mapper.map);
%〉
〈%@include file="footer.jsp" %〉
〈/body〉
〈/html〉

使用這些技術,只需單擊一個按鈕,JSP網頁即可彈出最新的、根據一個活動數據庫而動態生成的報表。CSV輸出可用于生成動態的Excel電子表格。XML輸出可為另一個Web應用程序提供服務,該應用程序將與它自己的后端數據庫進行通信。


小結

我們介紹了如何創建一個接口來定義DataBaseHandler的泛化行為,并用一個抽象類來實現它,以便將這個抽象類擴展成一個定制的、具體的數據庫處理程序,所有操作只需幾行Java代碼。SQLMapper類利用這種行為來透明連接一個關系數據庫,執行SQL查詢,并將數據轉換成一個DOM文檔對象。然后,通過應用一個XSL樣式表來獲取需要的輸出,從而完成一個DOM對象的轉換。隨后,輸出可由任何應用程序使用,只需采用一種有效的、易于實現的方式來提供需要的輸入。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 免费看黄色三级毛片 | 久草在线手机视频 | 一区在线免费视频 | 日韩做爰视频免费 | 欧美一级片一区 | 日韩黄色免费电影 | 久久久久国产成人免费精品免费 | 黄污在线观看 | 国产papa| 精品亚洲夜色av98在线观看 | 久在线播放 | www国产成人免费观看视频,深夜成人网 | chinese18 xxxx videos | 99精品视频在线免费观看 | 欧美成人免费在线视频 | 免费看a级片 | 色啪综合 | 久久亚洲激情 | 欧美成人三级视频 | 国产成人羞羞视频在线 | 国产亚洲综合精品 | 中文字幕1区2区 | 免费观看一级淫片 | 精品在线视频播放 | 黄污在线看 | 高清在线观看av | 成人aaaaa片毛片按摩 | 亚洲综合91 | 国产精品一区在线观看 | 成人国产精品一区 | 国产亚洲精品久久午夜玫瑰园 | 国产日韩大片 | 高清国产午夜精品久久久久久 | 露脸各种姿势啪啪的清纯美女 | 亚洲性爰| 欧美一级淫片免费视频黄 | 成人高清网站 | 369看片你懂的小视频在线观看 | 日韩欧美激情视频 | 成人三级黄色片 | 久久精品亚洲国产奇米99 |