在项目里面遇到了一些被解析的xml文件超过30M 或 60M 以上的情况, 现在已经不好去说为什么不在一开始产生xml的情况下就把xml 做小点,但是遇到这个问题后,我只能解决问题了,解决问题同时害怕重复发明轮子,我也去看了下现有的xml 解析东西,jdom 的SAXBuilder和 dom4j 的SAXReader都是把XML文件一次读入,xml文件过来 会报溢出的异常 但即使SAXParser是可以批量读入解析,但它也是一次解析完,假设XML文件中有一万条数据,解析后就必须在内存中放这么多的对象 个人觉得这样有些不灵活,就自己做了个小东西来切分 但前提是这个xml文件得有文件头 <?xml version="1.0" encoding="GBK"?> encoding必须跟文件编码格式一致 ,不然解析的时候会出乱码。
个人水平有限,但很希望得到大家的指正,希望大家不吝啬手中的砖头
package searchRing.ring.util.xmlBufferTool;
import java.io.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class XMLBufferTool {
private static final int defaultLineCount = 10;
private static final int defaultMaxOutputSize = 50;
private static final Pattern elementPattern = Pattern.compile("<[a-zA-Z]+>");
private static final Pattern charSetPattern = Pattern.compile("<[?][[0-9a-zA-Z]|[\\s]|[=]|[\"]|[.]|[-]]+[?]>");
private StringBuffer xmlContentBuffer;
/* just used to store and output the data divided */
XMLOutputBuffer xmlOutput;
private String charSetTitle = "";
private String rootElemetMark = "";
private String childElementMark = "";
InputStreamReader bufferedReader;
InputStream fileInputStream;
public XMLBufferTool(String xmlFilePath) {
this.xmlContentBuffer = new StringBuffer();
try {
this.fileInputStream = new FileInputStream(xmlFilePath);
// bufferedReader = new InputStreamReader(fileInputStream, "UTF-8");
String charSet = getCharSet(xmlFilePath);
if (charSet != null)
bufferedReader = new InputStreamReader(fileInputStream, charSet);
else
bufferedReader = new InputStreamReader(fileInputStream);
} catch (FileNotFoundException fe) {
fe.printStackTrace();
} catch (UnsupportedEncodingException uee) {
uee.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
try {
preparePaser();
} catch (IOException ie) {
ie.printStackTrace();
}
}
public String getCharSetTitle() {
return charSetTitle;
}
public String getRootElemetMark() {
return rootElemetMark;
}
private String getCharSet(String filePath) throws IOException {
char temp[] = new char[512];
FileInputStream tempInput = new FileInputStream(filePath);
InputStreamReader tempReader = new InputStreamReader(tempInput);
int i = tempReader.read(temp);
tempReader.close();
tempInput.close();
if (i < 0)
return null;
String tempStr = new String(temp);
Matcher m = charSetPattern.matcher(tempStr);
if (m.find()) {
String charSetStr = tempStr.substring(m.start(), m.end());
Pattern tempP = Pattern.compile("[\"][[0-9a-zA-Z]|[-]]+[\"]");
Matcher tempM = tempP.matcher(charSetStr);
if (tempM.find()) {
String charSet = charSetStr.substring(tempM.start(), tempM.end());
return charSet.substring(1, charSet.length() - 1);
}
}
return null;
}
private void preparePaser() throws IOException {
readSomeLine(defaultLineCount);
Matcher m = charSetPattern.matcher(xmlContentBuffer);
if (m.find()) {
this.charSetTitle = this.xmlContentBuffer.substring(m.start(), m.end());
this.xmlContentBuffer.delete(0, m.end());
}
m = elementPattern.matcher(xmlContentBuffer);
if (m.find()) {
this.rootElemetMark = this.xmlContentBuffer.substring(m.start(), m.end());
this.xmlContentBuffer.delete(0, m.end());
}
m = elementPattern.matcher(xmlContentBuffer);
if (m.find()) {
this.childElementMark = this.xmlContentBuffer.substring(m.start(), m.end());
}
this.xmlOutput = new XMLOutputBuffer(this.childElementMark);
parserBuffer();
}
private int readSomeLine(int lineCount) throws IOException {
char buffer[] = new char[1024];
int i = 0;
int index = 0;
/* be careful of the sequence of the boolean caculation */
while (i++ < lineCount && (index = this.bufferedReader.read(buffer)) > 0) {
xmlContentBuffer.append(buffer, 0, index);
}
return index;
}
private void parserBuffer() {
int lastIndex = this.xmlContentBuffer.lastIndexOf(this.childElementMark);
if (lastIndex > 0) {
this.xmlOutput.append(this.xmlContentBuffer.substring(0, lastIndex));
this.xmlContentBuffer.delete(0, lastIndex);
}
}
public StringBuffer popDividedDataAfterParser() throws IOException {
while (this.xmlOutput.getItemCount() < defaultMaxOutputSize) {
int i = readSomeLine(defaultLineCount);
parserBuffer();
if (i < 0)
break;
}
if (this.xmlOutput.getItemCount() == 0)
return null;
StringBuffer returnSB = this.xmlOutput.getXmlOutput();
this.xmlOutput.clearBuffer();
return returnSB.insert(0, this.rootElemetMark).append(this.rootElemetMark.replaceFirst("<", "</"));
}
public static void main(String args[]) throws Exception {
String str = "F:/ringInfoXML/ringTime.xml";
XMLBufferTool xmlb = new XMLBufferTool(str);
StringBuffer s = xmlb.popDividedDataAfterParser();
int i = 0;
Matcher m = Pattern.compile("<ring>").matcher(s);
while (m.find())
i++;
System.out.println(i);
System.out.println(s);
}
private static class XMLOutputBuffer {
private StringBuffer xmlOutput;
private int itemCount;
private Pattern markPattern;
XMLOutputBuffer(String markStr) {
this.markPattern = Pattern.compile(markStr);
xmlOutput = new StringBuffer();
itemCount = 0;
}
public void append(String str) {
if (str == null || "".equals(str))
return;
this.xmlOutput.append(str);
Matcher m = this.markPattern.matcher(str);
while (m.find())
this.itemCount++;
}
public void clearBuffer() {
xmlOutput = new StringBuffer();
this.itemCount = 0;
}
public StringBuffer getXmlOutput() {
return xmlOutput;
}
public int getItemCount() {
return itemCount;
}
}
}
代码中popDividedDataAfterParser() 输出的StringBuffer 可用来初始化一个 StringReader 再给dom4j 的saxReader去解析,这样联合一起用, 想处理多少,就先分出来解析多少,特别适合多线程的生产者和消费者的那种情况,希望对大家有用
分享到:
相关推荐
XML文件的解析--libxml库函数解释
解析XML--自己解析XML--自己解析XML--自己解析XML--自己解析XML--自己解析XML--自己解析XML--自己
用相应的类来存储Xml文件的数据来实现对XML文件数据的解析。
赠送Maven依赖信息文件:xmlgraphics-commons-2.1.pom; 包含翻译后的API文档:xmlgraphics-commons-2.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.xmlgraphics:xmlgraphics-commons:2.1; 标签:...
android解析xml文件的方式--PULL.pdf
Xml之DOM解析--学生成绩管理系统 根据方立勋视频,自己敲出来的
XML解析器-简单工厂模式.doc XML解析器-简单工厂模式.doc
C++实现对xml文件的解析,C++实现对xml文件的解析,C++实现对xml文件的解析。
赠送Maven依赖信息文件:jakarta.xml.bind-api-2.3.3.pom; 包含翻译后的API文档:jakarta.xml.bind-api-2.3.3-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:jakarta.xml.bind:jakarta.xml.bind-api:...
kettle批量解析多个xml文件,适合于批量数据导入,生产环境直接测试,肯定没有问题
自己写的一个xml文档解析类,实现对标准xml文档解析:读取、查询、删除、添加、保存等基本操作. 开发工具vs2008
* 本类是专门解析XML文件的,主要用于为系统读取自己的配置文件时提供最方便的解析操作 * @author HX * */ public class XmlManager { /** * 得到某节点下某个属性的值 * @param element 要获取属性的...
Android解析xml(3)---Pull解析
cxf jar xmlschema-core-2.0.jar
XML文件解析工具类
C#操作XML文件完整源码-LSP.rarC#操作XML文件完整源码-LSP.rarC#操作XML文件完整源码-LSP.rar
一个项目同时用dom解析和sax解析xml文件貌似会报错,项目框架建一直是用sax和dom4j解析xml文件的。当我用dom解析xml文件。导入包后就报错识别不了xml文件的编码格式。于是做了一个sax解析xml文件的实例
开源跨平台XML解析器-LIBXML2--库-hpux 11/ia64,源代码可从http://xmlsoft.org/downloads.html或资源“开源跨平台XML解析器-LIBXML2--C源代码及VC6工程文件”获取
TinyXML-2 是一个简单、小型、高效的 C++ XML 解析器,可以被轻松集成到其他程序中。它使用文档对象模型(DOM)的方式解析XML,可解析 XML 文档,并根据该文档构建可读取、修改和保存的文档对象模型。 作为XML解析...
演示web.xml文件中error-page标签的使用.zip,欢迎下载!