使用 SQL 结果创建 XML 文档
来源:互联网 发布:淘宝卖家故意不发货 编辑:程序博客网 时间:2024/04/29 21:01
使用 SQL 结果创建 XML 文档
算法
创建新 XML 文档的过程如下:
1 解析映射文件,以便获得必要的信息,包括要检索的数据在内。
2 检索源查询。这允许根据映射文件动态检索数据。
3 将数据存储到文档对象中。随后我们将从这个临时文档中拉取数据,以便根据映射创建目标文档。
4 检索数据映射,使应用程序可以使用它。
5 循环遍历原始数据。分析每一行数据,并将其重新映射到新结构。
6 检索元素映射。映射文件定义了从临时文档中按照怎样的顺序拉取哪些数据。
7 为新文档添加元素。检索数据之后,将其添加到新文档的新名称下。
8 为新文档添加属性。最后,将任何属性添加到恰当的元素中。
解析映射文件
创建新文档的第一步是检索映射,这只能通过解析映射文件完成。请注意,由于此文件也包括对最终将检索的数据的引用,因此您必须先解析此文件,然后才能执行数据库操作。
...
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class Pricing extends Object {
public static void main (String args[]){
//Create the Document object
Document mapDoc = null;
try {
//Create the DocumentBuilderFactory
DocumentBuilderFactory dbfactory =
DocumentBuilderFactory.newInstance();
//Create the DocumentBuilder
DocumentBuilder docbuilder = dbfactory.newDocumentBuilder();
//Parse the file to create the Document
mapDoc = docbuilder.parse("mapping.xml");
} catch (Exception e) {
System.out.println("Problem creating document: "+e.getMessage());
}
//For the JDBC-ODBC bridge, use
//driverName = "sun.jdbc.odbc.JdbcOdbcDriver"
//and
//connectURL = "jdbc:odbc:pricing"
String driverName = "JData2_0.sql.$Driver";
String connectURL = "jdbc:JDataConnect://127.0.0.1/pricing";
Connection db = null;
...
检索源查询
接下来检索 data 元素的 sql 属性中存储的源查询。
...
import org.w3c.dom.Element;
import org.w3c.dom.Node;
...
System.out.println("Problem creating document: "+e.getMessage());
}
//Retrieve the root element
Element mapRoot = mapDoc.getDocumentElement();
//Retrieve the (only) data element and cast it to Element
Node dataNode = mapRoot.getElementsByTagName("data").item(0);
Element dataElement = (Element)dataNode;
//Retrieve the sql statement
String sql = dataElement.getAttribute("sql");
//Output the SQL statement
System.out.println(sql);
//For the JDBC-ODBC bridge, use
//driverName = "sun.jdbc.odbc.JdbcOdbcDriver"
//and
//connectURL = "jdbc:odbc:pricing"
String driverName = "JData2_0.sql.$Driver";
String connectURL = "jdbc:JDataConnect://127.0.0.1/pricing";
Connection db = null;
...
首先确定根元素,随后检索 data 节点。由于仅有一个 data 元素,因此您可以直接检索。类似的技术也可以用于通过多个依序运行的查询构建文档。
最后,将 Node 强制转换为 Element,以便获得 Attribute 值。
删除之前的输出语句,运行应用程序,显示 SQL 语句作为输出。
图 9. SQL 语句作为输出
将数据存储到文档对象中
从数据库中成功提取数据之后,数据将存储在临时的 Document 之中。通用方法是为每个数据行创建一个 row 元素,将每列表示为根据该列命名的一个元素,将数据本身作为元素的内容。
...
public static void main (String args[]){
Document mapDoc = null;
//Define a new Document object
Document dataDoc = null;
try {
//Create the DocumentBuilderFactory
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
//Create the DocumentBuilder
DocumentBuilder docbuilder = dbfactory.newDocumentBuilder();
//Parse the file to create the Document
mapDoc = docbuilder.parse("mapping.xml");
//Instantiate a new Document object
dataDoc = docbuilder.newDocument();
} catch (Exception e) {
System.out.println("Problem creating document: "+e.getMessage());
}
...
ResultSetMetaData resultmetadata = null;
//Create a new element called "data"
Element dataRoot = dataDoc.createElement("data");
try {
statement = db.createStatement();
resultset = statement.executeQuery("select * from products");
resultmetadata = resultset.getMetaData();
int numCols = resultmetadata.getColumnCount();
while (resultset.next()) {
//For each row of data
//Create a new element called "row"
Element rowEl = dataDoc.createElement("row");
for (int i=1; i <= numCols; i++) {
//For each column, retrieve the name and data
String colName = resultmetadata.getColumnName(i);
String colVal = resultset.getString(i);
//If there was no data, add "and up"
if (resultset.wasNull()) {
colVal = "and up";
}
//Create a new element with the same name as the column
Element dataEl = dataDoc.createElement(colName);
//Add the data to the new element
dataEl.appendChild(dataDoc.createTextNode(colVal));
//Add the new element to the row
rowEl.appendChild(dataEl);
}
//Add the row to the root element
dataRoot.appendChild(rowEl);
}
} catch (SQLException e) {
System.out.println("SQL Error: "+e.getMessage());
} finally {
System.out.println("Closing connections...");
try {
db.close();
} catch (SQLException e) {
System.out.println("Can't close connection.");
}
}
//Add the root element to the document
dataDoc.appendChild(dataRoot);
}
}
具体来说,参见上面的代码示例,首先创建一个空文档以及根元素 data。对于数据库中的每一行,创建一个 row 元素,为每一列创建一个独立的元素,并将其添加到行中。最后,将各 row 元素添加到根,将根添加到 Document。
检索数据映射
获得数据之后,便可以开始将其映射到新结构:从解析后的映射文档中检索映射。先检索根元素和行元素中的信息,随后检索元素映射本身。
...
import org.w3c.dom.NodeList;
...
dataDoc.appendChild(dataRoot);
//Retrieve the root element (also called "root")
Element newRootInfo =
(Element)mapRoot.getElementsByTagName("root").item(0);
//Retrieve the root and row information
String newRootName = newRootInfo.getAttribute("name");
String newRowName = newRootInfo.getAttribute("rowName");
//Retrieve information on elements to be built in the new document
NodeList newNodesMap = mapRoot.getElementsByTagName("element");
}
}
有了这些信息之后,就可以构建新的 Document。
循环遍历原始数据
每个原始行均作为一个 row 元素存储在临时文件之中。您需要循环遍历这些元素,将其作为 NodeList 检索。
...
NodeList newNodesMap = mapRoot.getElementsByTagName("element");
//Retrieve all rows in the old document
NodeList oldRows = dataRoot.getElementsByTagName("row");
for (int i=0; i < oldRows.getLength(); i++){
//Retrieve each row in turn
Element thisRow = (Element)oldRows.item(i);
}
...
检索元素映射
既然已经获得了数据和映射信息,下面就可以开始构建新的 Document。对于每一行,循环遍历映射,确定从临时 Document 中检索数据列的顺序,并确定在将其添加到新的 Document 中时应对其采用什么样的名称。
...
for (int i=0; i < oldRows.getLength(); i++){
//Retrieve each row in turn
Element thisRow = (Element)oldRows.item(i);
for (int j=0; j < newNodesMap.getLength(); j++) {
//For each node in the new mapping, retrieve the information
//First the new information...
Element thisElement = (Element)newNodesMap.item(j);
String newElementName = thisElement.getAttribute("name");
//Then the old information
Element oldElement =
(Element)thisElement.getElementsByTagName("content").item(0);
String oldField = oldElement.getFirstChild().getNodeValue();
}
}
...
对于 newNodesMap 中的每一个元素,应用程序都会检索新元素名称,随后会检索要检索的旧元素的名称。
向新文档添加元素
将新元素添加到文档之中非常简单,只需使用恰当的名称创建新元素,随后检索恰当的数据并将其设置为元素的内容即可。
...
public static void main (String args[]){
Document mapDoc = null;
Document dataDoc = null;
//Create the new Document
Document newDoc = null;
try {
//Create the DocumentBuilderFactory
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
//Create the DocumentBuilder
DocumentBuilder docbuilder = dbfactory.newDocumentBuilder();
//Parse the file to create the Document
mapDoc = docbuilder.parse("mapping.xml");
//Instantiate a new Document object
dataDoc = docbuilder.newDocument();
//Instantiate the new Document
newDoc = docbuilder.newDocument();
} catch (Exception e) {
System.out.println("Problem creating document: "+e.getMessage());
}
...
//Retrieve the root element (also called "root")
Element newRootInfo = (Element)mapRoot.getElementsByTagName("root").item(0);
//Retrieve the root and row information
String newRootName = newRootInfo.getAttribute("name");
String newRowName = newRootInfo.getAttribute("rowName");
//Retrieve information on elements to be built in the new document
NodeList newNodesMap = mapRoot.getElementsByTagName("element");
//Create the final root element with the name from the mapping file
Element newRootElement = newDoc.createElement(newRootName);
NodeList oldRows = dataRoot.getElementsByTagName("row");
for (int i=0; i < oldRows.getLength(); i++){
//For each of the original rows
Element thisRow = (Element)oldRows.item(i);
//Create the new row
Element newRow = newDoc.createElement(newRowName);
for (int j=0; j < newNodesMap.getLength(); j++) {
//Get the mapping information for each column
Element thisElement = (Element)newNodesMap.item(j);
String newElementName = thisElement.getAttribute("name");
Element oldElement =
(Element)thisElement.getElementsByTagName("content").item(0);
String oldField = oldElement.getFirstChild().getNodeValue();
//Get the original values based on the mapping information
Element oldValueElement =
(Element)thisRow.getElementsByTagName(oldField).item(0);
String oldValue =
oldValueElement.getFirstChild().getNodeValue();
//Create the new element
Element newElement = newDoc.createElement(newElementName);
newElement.appendChild(newDoc.createTextNode(oldValue));
//Add the new element to the new row
newRow.appendChild(newElement);
}
//Add the new row to the root
newRootElement.appendChild(newRow);
}
//Add the new root to the document
newDoc.appendChild(newRootElement);
}
}
首先,需要创建新的 Document,随后创建新的根元素,其名称会获取自映射信息。对于临时 Document 中的每一行,可以使用映射中指定的 newRowName 为新行创建一个元素。
对于每一行,循环遍历映射中指定的各新元素,并检索原始数据。在上一节中,您已经按顺序检索了 content 元素的文本。现在您可以使用此信息来确定将按照什么样的顺序从临时行中检索哪些节点。获得了旧数据和新名称之后,可以创建新元素并将其添加到行中。
最后,将新行添加到根元素,将根元素添加到 Document。最后要添加的内容就是属性。
为新文档添加属性
新 Document 已经接近完成。您已经添加了新元素,但尚未添加可能指定的任何属性。按照与添加新元素本身相似的方式添加这些属性。然而,一个元素有可能具有多项属性,因此在代码中必须考虑到这个问题。完成这项任务的最简单的方法就是检索 attribute 元素,并将其置入 NodeList,随后遍历列表,处理各元素。对于每一个所需属性,通过原始 Document 确定字段名称,并确定其在新Document 中的名称。
...
Element newElement = newDoc.createElement(newElementName);
newElement.appendChild(newDoc.createTextNode(oldValue));
//Retrieve list of new elements
NodeList newAttributes =
thisElement.getElementsByTagName("attribute");
for (int k=0; k < newAttributes.getLength(); k++) {
//For each new attribute
//Get the mapping information
Element thisAttribute = (Element)newAttributes.item(k);
String oldAttributeField =
thisAttribute.getFirstChild().getNodeValue();
String newAttributeName = thisAttribute.getAttribute("name");
//Get the original value
oldValueElement =
(Element)thisRow.getElementsByTagName(oldAttributeField).item(0);
String oldAttributeValue =
oldValueElement.getFirstChild().getNodeValue();
//Create the new attribute
newElement.setAttribute(newAttributeName, oldAttributeValue);
}
//Add the element to the new row
newRow.appendChild(newElement);
}
//Add the new row to the root
newRootElement.appendChild(newRow);
...
最终文档
这个过程结束时,newDoc 包含采用新格式的旧信息。之后即可在另一个应用程序中使用它,或者使用 XSLT 或其他方法实现进一步的转换。
<pricingInfo>
<product>
<description product_number="1">Filet Mignon</description>
<quantity>1</quantity>
<size>1</size>
<sizeUnit>item</sizeUnit>
<quantityPrice>40</quantityPrice>
</product>
<product>
<description product_number="2">Filet Mignon</description>
<quantity>11</quantity>
<size>1</size>
<sizeUnit>item</sizeUnit>
<quantityPrice>30</quantityPrice>
</product>
<product>
<description product_number="3">Filet Mignon</description>
<quantity>101</quantity>
<size>1</size>
<sizeUnit>item</sizeUnit>
<quantityPrice>20</quantityPrice>
</product>
<product>
<description product_number="4">Prime Rib</description>
<quantity>1</quantity>
<size>1</size>
<sizeUnit>lb</sizeUnit>
<quantityPrice>20</quantityPrice>
</product>
<product>
<description product_number="5">Prime Rib</description>
<quantity>101</quantity>
<size>1</size>
<sizeUnit>lb</sizeUnit>
<quantityPrice>15</quantityPrice>
</product>
...
- 使用 SQL 结果创建 XML 文档
- java 根据结果集创建XML文档
- 使用XML创建Excel文档
- 使用DOM4J创建XML文档
- 使用DOM创建XML文档
- 使用XML创建Excel文档
- 使用PYTHON创建XML文档
- php使用 DOM 创建xml文档
- Java:使用JDOM创建XML文档
- 使用DOM创建和操作XML文档
- 使用CMarkup创建及解析XML文档
- C#创建XML文档
- DOM4J创建XML文档
- JDOM创建XML文档
- MS XML 文档创建
- 创建xml文档对象
- 创建XML文档
- 创建XML文档
- MVC 站点放在虚拟目录下 的 图片和JS文件路径设置
- 异常备忘:java.lang.UnsupportedClassVersionError: Bad version number in .class file
- 声明表变量
- 十款精美的免费单页网站PSD模板分享
- Java回调函数的理解 .
- 使用 SQL 结果创建 XML 文档
- ios5 storyboard 代码获取独立的 viewController对象
- 防中暑必须补充盐和水
- 免费和高级定制后台管理模板
- 软件开发最重要的是可测性
- 用户角色权限设计
- 如何理解笛卡尔积
- 翻译ANDROID-MK R7版本
- 下载(二)客户端通过C# 代码直接从服务器下载文件到本地