SAX解析xml时,数据内容超过2k时,数据被分段,信息不完整

public void characters(char ch[],int start,int length)throws SAXException

in ContentHandler interface:

关于参数ch的解释:

 String s = new String(ch,start,length)

并不一定就能完整的表示 元素的值. 如果xml文档交长, 有可能一个元素的值会被分两次读入,所以如果只适用上面的方法去获得元素的值,很可能得到的不完整的数据.

原因:

SAX parser 分块读取流, 默认为一次读取2K字节. (ch 里面不仅包含元素的值信息,其实它是整个xml文档的一个部分,也就是说,分析器每次从文档中读取2K字节,放到这个数组中,然后通过start和length来划分出属于value的部分.这样的话,不能保证最后一个元素的值是完全被包含在这个ch中的).

所以我们还是要进行一些额外的操作才能通过 characters(char ch[],int start,int length)获得完整的element value.

 

JAVA程序读取XML配置文件 完整实例

方法一:

package org.luozhh.myzhint.test;

import java.util.Properties;

public class ReadConfigXml {

private Properties props;

public ReadConfigXml(String url){
   ParseXML myRead = new ParseXML();
   try {
    myRead.parse(url);
    props = new Properties();
    props = myRead.getProps();
   } catch (Exception e) {
    e.printStackTrace();
   }
}

public String getHost(){
   return props.getProperty("host");
}

public String getDataBase(){
   return props.getProperty("database");
}

public String getUserName(){
   return props.getProperty("username");
}

public String getPassWord(){
   return props.getProperty("password");
}

public Properties getProps(){
   return this.props;
}
}

 

package org.luozhh.myzhint.test;

import java.util.Properties;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class ParseXML {

// 定义一个Properties 用来存放属性值
private Properties props;

public Properties getProps() {
   return this.props;
}

public void parse(String filename) throws Exception {

   // 将我们的解析器对象化
   ConfigParser handler = new ConfigParser();
  
   // 获取SAX工厂对象
   SAXParserFactory factory = SAXParserFactory.newInstance();
   factory.setNamespaceAware(false);
   factory.setValidating(false);
  
   // 获取SAX解析
   SAXParser parser = factory.newSAXParser();
   try{
    // 将解析器和解析对象xml联系起来,开始解析
    parser.parse(filename, handler);
    // 获取解析成功后的属性
    props = handler.getProps();
   }finally{
    factory=null;
    parser=null;
    handler=null;
   }
}
}

package org.luozhh.myzhint.test;

import java.util.Properties;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ConfigParser extends DefaultHandler {

//定义一个Properties 用来存放属性值
private Properties props;

private String currentSet;

private String currentName;

private StringBuffer currentValue = new StringBuffer();

// 构建器初始化props
public ConfigParser() {
   this.props = new Properties();
}

public Properties getProps() {
   return this.props;
}

// 定义开始解析元素的方法. 这里是将中的名称xxx提取出来.
/**
* qName:XML节点名称
* Attributes:qName节点的所有属性值
*/
public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {
   currentValue.delete(0, currentValue.length());
   this.currentName = qName;
}

// 这里是将之间的值加入到currentValue
public void characters(char[] ch, int start, int length)
    throws SAXException {
   currentValue.append(ch, start, length);
}

// 在遇到结束后,将之前的名称和值一一对应保存在props中
public void endElement(String uri, String localName, String qName)
    throws SAXException {
   props.put(qName.toLowerCase(), currentValue.toString().trim());
}

}

package org.luozhh.myzhint.test;

import java.util.Properties;

public class Conn {

public static void main(String args[]){
  
   ReadConfigXml r = new ReadConfigXml("WebRoot/WEB-INF/Conn.xml");
   Properties props = r.getProps();
   System.out.println(props.size());
   System.out.println(props.getProperty("company"));
  
}
}

Conn.xml

<?xml version="1.0" encoding="UTF-8"?>
<webgis>
<host>127.0.0.1</host>
<database>mysql</database>
<username>root</username>
<password>root</password>
<company>lt</company>
</webgis>

方法二:

package org.luozhh.myzhint.test;

import java.io.CharArrayWriter;
import java.io.FileReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
/*
* XML的JAVA 解析,效率比较底
*/
public class XMLParserDemo extends DefaultHandler {

private Stack tagStack = new Stack();

private Vector items = new Vector();

private Map map = new HashMap();

private CharArrayWriter contents = new CharArrayWriter();

String temp = null;

public void startElement(String namespaceURI, String localName,
    String qName, Attributes attr) throws SAXException {

   contents.reset();
   tagStack.push(localName);
   System.out.println("path found: [" + getTagPath(tagStack) + "]");

}

public void endElement(String namespaceURI, String localName, String qName)
    throws SAXException {

   tagStack.pop();
//   System.out.println(this.contents.toString());
   if(this.temp != null || "".equals(this.temp)){
    map.put(qName, this.contents.toString());
   }
}

/*
* 将内容通过字符数组的形式储存
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length)
    throws SAXException {
   contents.write(ch, start, length);
  
}

private String getTagPath(Stack tagStack) {

   String buffer = "";
   Enumeration e = tagStack.elements();
   while (e.hasMoreElements()) {
    buffer = buffer + "/" + (String) e.nextElement();
   }
  
   this.temp = buffer;
   return buffer;
}

public Map getMap(){
   return this.map;
}

public static void main(String args[]){
  
   try {
    XMLReader xr = XMLReaderFactory.createXMLReader();
    XMLParserDemo ex1 = new XMLParserDemo();
    xr.setContentHandler(ex1);
    xr.parse(new InputSource(new FileReader("WebRoot/WEB-INF/Conn.xml")));
   
    Map all = ex1.getMap();
    System.out.println(all.get("company"));
   } catch (Exception e) {
    e.printStackTrace();
   }
}

}

方法3:

package org.luozhh.myzhint.test;

import java.io.CharArrayWriter;
import java.io.FileReader;
import java.util.Enumeration;
import java.util.Stack;
import java.util.Vector;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

public class Example1 extends DefaultHandler {
// 用来跟踪当前打开的标签名的堆栈
// (所谓的”startElement”但不包括”endElement”)
private Stack tagStack = new Stack();

// 物品名的本地向量表...
private Vector items = new Vector();

// 顾客名...
private String customer;

// 用于收集来自”characters” SAX事件的数据的缓存。
private CharArrayWriter contents = new CharArrayWriter();

// 重载DefaultHandler类以拦截SAX事件的方法。
//
// 关于所有有效事件的详细内容,参见org.xml.sax.ContentHandler。
//

public void startElement(String namespaceURI, String localName,
    String qName, Attributes attr) throws SAXException {

   contents.reset();

   // 标签名入栈...
   tagStack.push(localName);

   // 显示找到的当前路径...
   System.out.println("path found: [" + getTagPath() + "]");

}

public void endElement(String namespaceURI, String localName, String qName)
    throws SAXException {

   if (getTagPath().equals("/CustomerOrder/Customer/Name")) {
    customer = contents.toString().trim();
   } else if (getTagPath().equals("/CustomerOrder/Items/Item/Name")) {
    items.addElement(contents.toString().trim());
   }

   // 清空堆栈...
   tagStack.pop();
}

public void characters(char[] ch, int start, int length)
    throws SAXException {
   // 将内容收集到一个缓存中
   contents.write(ch, start, length);

}

// 从堆栈的当前状态建立路径字符串...
//
// 效率很低,但是我们迟些再讨论...
private String getTagPath() {

   // 创建路径字符串...
   String buffer = "";
   Enumeration e = tagStack.elements();
   while (e.hasMoreElements()) {
    buffer = buffer + "/" + (String) e.nextElement();
   }
   return buffer;
}

public Vector getItems() {
   return items;
}

public String getCustomerName() {
   return customer;
}

public static void main(String[] argv) {

   System.out.println("Example1:");
   try {

    // 创建SAX 2解析器...
    XMLReader xr = XMLReaderFactory.createXMLReader();

    // 安装ContentHandler...
    Example1 ex1 = new Example1();
    xr.setContentHandler(ex1);

    System.out.println();
    System.out.println("Tag paths located:");

    // 解析文件...
    xr.parse(new InputSource(new FileReader("src/org/luozhh/myzhint/test/Example1.xml")));

    System.out.println();
    System.out.println("Names located:");

    // 显示Customer
    System.out.println("Customer Name: " + ex1.getCustomerName());

    // 把所有的定购商品显示到标准输出...
    System.out.println("Order Items: ");
    String itemName;
    Vector items = ex1.getItems();
    Enumeration e = items.elements();
    while (e.hasMoreElements()) {
     itemName = (String) e.nextElement();
     System.out.println(itemName);
    }

   } catch (Exception e) {
    e.printStackTrace();
   }
}
}

你可能感兴趣的:(解析xml)