You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
7.5 KiB
226 lines
7.5 KiB
package com.fr.data; |
|
|
|
import com.fr.base.FRContext; |
|
import com.fr.general.ComparatorUtils; |
|
import com.fr.general.data.TableDataException; |
|
import org.xml.sax.Attributes; |
|
import org.xml.sax.SAXException; |
|
import org.xml.sax.helpers.DefaultHandler; |
|
|
|
import javax.xml.parsers.SAXParser; |
|
import javax.xml.parsers.SAXParserFactory; |
|
import java.io.File; |
|
import java.util.ArrayList; |
|
import java.util.List; |
|
|
|
/** |
|
* XMLParseDemoDataModel |
|
* <p> |
|
* DataModel是获取数据的接口 |
|
* <p> |
|
* 这里通过init方法一次性取数后,构造一个二维表对象来实现DataModel的各个取数方法 |
|
*/ |
|
public class XMLParseDemoDataModel extends AbstractDataModel { |
|
// 数据类型标识 |
|
public static final int COLUMN_TYPE_STRING = 0; |
|
public static final int COLUMN_TYPE_INTEGER = 1; |
|
public static final int COLUMN_TYPE_BOOLEAN = 2; |
|
|
|
// 缓存取出来的数据 |
|
protected List row_list = null; |
|
|
|
// 数据对应的节点路径 |
|
private String[] xPath; |
|
// 节点路径下包含的需要取数的节点 |
|
private XMLColumnNameType4Demo[] columns; |
|
|
|
private String filePath; |
|
|
|
public XMLParseDemoDataModel(String filename, String[] xPath, |
|
XMLColumnNameType4Demo[] columns) { |
|
this.filePath = filename; |
|
this.xPath = xPath; |
|
this.columns = columns; |
|
} |
|
|
|
/** |
|
* 取出列的数量 |
|
*/ |
|
public int getColumnCount() throws TableDataException { |
|
return columns.length; |
|
} |
|
|
|
/** |
|
* 取出相应的列的名称 |
|
*/ |
|
public String getColumnName(int columnIndex) throws TableDataException { |
|
if (columnIndex < 0 || columnIndex >= columns.length) |
|
return null; |
|
String columnName = columns[columnIndex] == null ? null |
|
: columns[columnIndex].getName(); |
|
|
|
return columnName; |
|
} |
|
|
|
/** |
|
* 取出得到的结果集的总的行数 |
|
*/ |
|
public int getRowCount() throws TableDataException { |
|
this.init(); |
|
return row_list.size(); |
|
} |
|
|
|
/** |
|
* 取出相应位置的值 |
|
*/ |
|
public Object getValueAt(int rowIndex, int columnIndex) |
|
throws TableDataException { |
|
this.init(); |
|
if (rowIndex < 0 || rowIndex >= row_list.size() || columnIndex < 0 |
|
|| columnIndex >= columns.length) |
|
return null; |
|
return ((Object[]) row_list.get(rowIndex))[columnIndex]; |
|
} |
|
|
|
/** |
|
* 释放一些资源,取数结束后,调用此方法来释放资源 |
|
*/ |
|
public void release() throws Exception { |
|
if (this.row_list != null) { |
|
this.row_list.clear(); |
|
this.row_list = null; |
|
} |
|
} |
|
|
|
/** ************************************************** */ |
|
/** ***********以上是实现DataModel的方法*************** */ |
|
/** ************************************************** */ |
|
|
|
/** ************************************************** */ |
|
/** ************以下为解析XML文件的方法**************** */ |
|
/** |
|
* ************************************************* |
|
*/ |
|
|
|
// 一次性将数据取出来 |
|
protected void init() throws TableDataException { |
|
if (this.row_list != null) |
|
return; |
|
|
|
this.row_list = new ArrayList(); |
|
try { |
|
// 使用SAX解析XML文件, 使用方法请参见JAVA SAX解析 |
|
SAXParserFactory f = SAXParserFactory.newInstance(); |
|
SAXParser parser = f.newSAXParser(); |
|
|
|
parser.parse(new File(XMLParseDemoDataModel.this.filePath), |
|
new DemoHandler()); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
FRContext.getLogger().error(e.getMessage(), e); |
|
} |
|
} |
|
|
|
/** |
|
* 基本原理就是解析器在遍历文件时 发现节点开始标记时,调用startElement方法 读取节点内部内容时,调用characters方法 |
|
* 发现节点结束标记时,调用endElement |
|
*/ |
|
private class DemoHandler extends DefaultHandler { |
|
private List levelList = new ArrayList(); // 记录当前节点的路径 |
|
private Object[] values; // 缓存一条记录 |
|
private int recordIndex = -1; // 当前记录所对应的列的序号,-1表示不需要记录 |
|
|
|
public void startElement(String uri, String localName, String qName, |
|
Attributes attributes) throws SAXException { |
|
// 记录下 |
|
levelList.add(qName); |
|
|
|
if (isRecordWrapTag()) { |
|
// 开始一条新数据的记录 |
|
values = new Object[XMLParseDemoDataModel.this.columns.length]; |
|
} else if (needReadRecord()) { |
|
// 看看其对应的列序号,下面的characters之后执行时,根据这个列序号来设置值存放的位置。 |
|
recordIndex = getColumnIndex(qName); |
|
} |
|
} |
|
|
|
public void characters(char[] ch, int start, int length) |
|
throws SAXException { |
|
if (recordIndex > -1) { |
|
// 读取值 |
|
String text = new String(ch, start, length); |
|
XMLColumnNameType4Demo type = XMLParseDemoDataModel.this.columns[recordIndex]; |
|
Object value = null; |
|
if (type.getType() == COLUMN_TYPE_STRING) { |
|
value = text; |
|
} |
|
if (type.getType() == COLUMN_TYPE_INTEGER) { |
|
value = new Integer(text); |
|
} else if (type.getType() == COLUMN_TYPE_BOOLEAN) { |
|
value = new Boolean(text); |
|
} |
|
|
|
values[recordIndex] = value; |
|
} |
|
} |
|
|
|
public void endElement(String uri, String localName, String qName) |
|
throws SAXException { |
|
try { |
|
if (isRecordWrapTag()) { |
|
// 一条记录结束,就add进list中 |
|
XMLParseDemoDataModel.this.row_list.add(values); |
|
values = null; |
|
} else if (needReadRecord()) { |
|
recordIndex = -1; |
|
} |
|
} finally { |
|
levelList.remove(levelList.size() - 1); |
|
} |
|
} |
|
|
|
// 正好匹配路径,确定是记录外部的Tag |
|
private boolean isRecordWrapTag() { |
|
if (levelList.size() == XMLParseDemoDataModel.this.xPath.length |
|
&& compareXPath()) { |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
// 需要记录一条记录 |
|
private boolean needReadRecord() { |
|
if (levelList.size() == (XMLParseDemoDataModel.this.xPath.length + 1) |
|
&& compareXPath()) { |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
// 是否匹配设定的XPath路径 |
|
private boolean compareXPath() { |
|
String[] xPath = XMLParseDemoDataModel.this.xPath; |
|
for (int i = 0; i < xPath.length; i++) { |
|
if (!ComparatorUtils.equals(xPath[i], levelList.get(i))) { |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
// 获取该字段的序号 |
|
private int getColumnIndex(String columnName) { |
|
XMLColumnNameType4Demo[] nts = XMLParseDemoDataModel.this.columns; |
|
for (int i = 0; i < nts.length; i++) { |
|
if (ComparatorUtils.equals(nts[i].getName(), columnName)) { |
|
return i; |
|
} |
|
} |
|
|
|
return -1; |
|
} |
|
} |
|
} |