xml是用来描述一组数据的规范,在不同系统交互,或者通信的过程中,我们往往使用到它,所以对于xml解析用的也是比较多的。本文没有依赖任何第三方jar包,就是jdk本身的API完成,支持任意复杂的xml的解析,有自定义handler供实现。
package com.epoint.utility.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.xml.sax.InputSource;
/**
* XML读取工具类,依赖jar包:无
*
* @author komojoemary
* @version [版本号, 2010-11-19]
*/
public class ReadXML
{
/**
* 判断依据1:节点文本内容不为空
*/
public static final String JUDGEMENT_BASIS_TYPE1 = "textContentNotNull";
/**
* 判断依据2:节点文本内容为空
*/
public static final String JUDGEMENT_BASIS_TYPE2 = "textContentNull";
/**
* 判断依据3:属性不为空
*/
public static final String JUDGEMENT_BASIS_TYPE3 = "attributeNotNull";
/**
* 判断依据4:属性为空
*/
public static final String JUDGEMENT_BASIS_TYPE4 = "attributeNull";
/**
* 默认的判断依据是节点文本内容不为空
*/
private String judgementBasis = JUDGEMENT_BASIS_TYPE1;
/**
* 是否仅获取一个唯一的节点
*/
private boolean isOnly = false;
/**
* 自定义xml解析接口
*/
private XmlParserHandler xmlParserHandler = null;
private boolean refresh = false;
private String filePath = null;
public ReadXML() {
}
public ReadXML(XmlParserHandler xmlParserHandler) {
this.xmlParserHandler = xmlParserHandler;
}
public ReadXML(String judgementBasis) {
this.judgementBasis = judgementBasis;
}
/************************************* 下面18个是对外公布的接口 ***********************************************/
/**
* 根据节点tag从xml文件中解析获取一个满足条件的xml节点的文本值
*
* @param filePath
* 文件路径
* @param tagName
* 节点tag
* @return String
*/
public String getTextContentByTagFromFile(String filePath, String tagName) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, filePath, true), tagName, null, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0).getTextValue();
}
return null;
}
/**
* 根据节点tag从xml文件中解析获取一个满足条件的xml节点
*
* @param filePath
* 文件路径
* @param tagName
* 节点tag
* @return XMLNode
*/
public XMLNode getXMLNodeByTagFromFile(String filePath, String tagName) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, filePath, true), tagName, null, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0);
}
return null;
}
/**
* 根据节点文本内容从xml文件中解析获取一个满足条件的xml节点
*
* @param filePath
* 文件路径
* @param text
* 节点文本内容
* @return XMLNode
*/
public XMLNode getXMLNodeByTextFromFile(String filePath, String text) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, filePath, true), null, text, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0);
}
return null;
}
/**
* 根据节点tag从xml文件中解析获取一组满足条件的xml节点
*
* @param filePath
* 文件路径
* @param tagName
* 节点tag
* @return List<XMLNode>
*/
public List<XMLNode> getXMLNodeListByTagFromFile(String filePath, String tagName) {
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, filePath, true), tagName, null, XMLNodeList);
return XMLNodeList;
}
/**
* 根据节点文本内容从xml文件中解析获取一组满足条件的xml节点
*
* @param filePath
* 文件路径
* @param text
* 节点文本内容
* @return List<XMLNode>
*/
public List<XMLNode> getXMLNodeListByTextFromFile(String filePath, String text) {
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, filePath, true), null, text, XMLNodeList);
return XMLNodeList;
}
/*-----------------------------------------------------------------------------------------------*/
/**
* 根据节点tag从xml文件内容中解析获取一个满足条件的xml节点的文本值
*
* @param content
* xml文件内容
* @param tagName
* 节点tag
* @return String
*/
public String getTextContentByTagFromStr(String content, String tagName) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, content, false), tagName, null, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0).getTextValue();
}
return null;
}
/**
* 根据节点tag从xml文件内容中解析获取一个满足条件的xml节点
*
* @param content
* xml文件内容
* @param tagName
* 节点tag
* @return XMLNode
*/
public XMLNode getXMLNodeByTagFromStr(String content, String tagName) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, content, false), tagName, null, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0);
}
return null;
}
/**
* 根据节点文本内容从xml文件内容中解析获取一个满足条件的xml节点
*
* @param content
* xml文件内容
* @param text
* 节点文本内容
* @return XMLNode
*/
public XMLNode getXMLNodeByTextFromStr(String content, String text) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, content, false), null, text, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0);
}
return null;
}
/**
* 根据节点tag从xml文件内容中解析获取一组满足条件的xml节点
*
* @param content
* xml文件内容
* @param tagName
* 节点tag
* @return List<XMLNode>
*/
public List<XMLNode> getXMLNodeListByTagFromStr(String content, String tagName) {
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, content, false), tagName, null, XMLNodeList);
return XMLNodeList;
}
/**
* 根据节点文本内容从xml文件内容中解析获取一组满足条件的xml节点
*
* @param content
* xml文件内容
* @param text
* 节点文本内容
* @return List<XMLNode>
*/
public List<XMLNode> getXMLNodeListByTextFromStr(String content, String text) {
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(null, content, false), null, text, XMLNodeList);
return XMLNodeList;
}
/*-----------------------------------------------------------------------------------------------*/
/**
* 根据节点tag从xml文件输入流中解析获取一个满足条件的xml节点的文本值
*
* @param ins
* xml文件输入流
* @param tagName
* 节点tag
* @return String
*/
public String getTextContentByTagFromInputStream(InputStream ins, String tagName) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(ins, null, false), tagName, null, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0).getTextValue();
}
return null;
}
/**
* 根据节点tag从xml文件输入流中解析获取一个满足条件的xml节点
*
* @param ins
* xml文件输入流
* @param tagName
* 节点tag
* @return XMLNode
*/
public XMLNode getXMLNodeByTagFromInputStream(InputStream ins, String tagName) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(ins, null, false), tagName, null, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0);
}
return null;
}
/**
* 根据节点文本内容从xml文件输入流中解析获取一个满足条件的xml节点
*
* @param ins
* xml文件输入流
* @param text
* 节点文本内容
* @return XMLNode
*/
public XMLNode getXMLNodeByTextFromInputStream(InputStream ins, String text) {
this.isOnly = true;
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(ins, null, false), null, text, XMLNodeList);
if (XMLNodeList.size() > 0) {
return XMLNodeList.get(0);
}
return null;
}
/**
* 根据节点tag从xml文件输入流中解析获取一组满足条件的xml节点
*
* @param ins
* xml文件输入流
* @param tagName
* 节点tag
* @return List<XMLNode>
*/
public List<XMLNode> getXMLNodeListByTagFromInputStream(InputStream ins, String tagName) {
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(ins, null, false), tagName, null, XMLNodeList);
return XMLNodeList;
}
/**
* 根据节点文本内容从xml文件输入流中解析获取一组满足条件的xml节点
*
* @param ins
* xml文件输入流
* @param text
* 节点文本内容
* @return List<XMLNode>
*/
public List<XMLNode> getXMLNodeListByTextFromInputStream(InputStream ins, String text) {
List<XMLNode> XMLNodeList = new ArrayList<XMLNode>();
getXMLNode(getDocument(ins, null, false), null, text, XMLNodeList);
return XMLNodeList;
}
/*-----------------------------------------------------------------------------------------------*/
/**
* 从一个xml文件中进行解析(针对于自定义解析接口的情况,实现比较复杂的xml解析逻辑)
*
* @param filePath
* 文件路径
*/
public void parserXmlFromFile(String filePath) {
getXMLNode(getDocument(null, filePath, true), null, null, null);
}
/**
* 从一个xml文件内容中进行解析(针对于自定义解析接口的情况,实现比较复杂的xml解析逻辑)
*
* @param filePath
* 文件内容
*/
public void parserXmlFromStr(String content) {
getXMLNode(getDocument(null, content, false), null, null, null);
}
/**
* 从一个xml文件输入流中进行解析(针对于自定义解析接口的情况,实现比较复杂的xml解析逻辑)
*
* @param ins
* 文件输入流
*/
public void parserXmlFromInputStream(InputStream ins) {
getXMLNode(getDocument(ins, null, false), null, null, null);
}
/************************************* 上面18个是对外公布的接口 ***********************************************/
/**
* 获取一个Document
*
* @param ins
* 输入流
* @param pathOrContent
* 文件路径or文件内容
* @param file
* 是否是文件
* @return Document
*/
private static Document getDocument(InputStream ins, String pathOrContent, boolean file) {
// 创建新的输入源SAX 解析器
SAXBuilder sb = new SAXBuilder();
// 创建一个dom对象
Document doc = null;
FileInputStream fis = null;
try {
// 如果输入流不为空,那么直接构造
if (ins != null) {
doc = sb.build(ins);
}
else {
InputSource source = null;
// 如果是文件,那么先构造一个文件
if (file) {
File newfile = new File(pathOrContent);
fis = new FileInputStream(newfile);
source = new InputSource(fis);
}
// 如果是内容,那么构造一个输入流
else {
StringReader reader = new StringReader(pathOrContent);
source = new InputSource(reader);
}
// 通过输入源构造一个Document
doc = sb.build(source);
}
}
catch (JDOMException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (fis != null) {
// 2011年3月14(关闭流)
try {
fis.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
// Transformer transformer;
// try {
// transformer = TransformerFactory.newInstance().newTransformer(new JDOMSource(doc));
// transformer.getOutputProperty("encoding");
// }
// catch (TransformerConfigurationException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// catch (TransformerFactoryConfigurationError e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// XSLTransformer transformer=new XSLTransformer(doc);
return doc;
}
public void getXMLNode(Document doc, String tagName, String text, List<XMLNode> XMLNodeList) {
// 取的根元素
Element root = doc.getRootElement();
// 递归整个dom tree
recureDocument(root, tagName, text, XMLNodeList);
// 如果需要更新
if (refresh) {
refreshXml(doc, filePath);
}
}
public static void refreshXml(Document doc, String filePath) {
Format f = Format.getPrettyFormat();
f.setEncoding("utf-8");
f.setLineSeparator("\r\n");
XMLOutputter outputter = new XMLOutputter(f);
try {
FileWriter writer = new FileWriter(filePath);
outputter.output(doc, writer);
writer.close();
}
catch (IOException e) {
e.printStackTrace();
}
// try {
// Transformer transformer = TransformerFactory.newInstance().newTransformer();
// transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// transformer.transform(new JDOMSource(doc), new StreamResult(filePath));
// }
// catch (TransformerException e) {
// e.printStackTrace();
// }
// catch (TransformerFactoryConfigurationError e) {
// e.printStackTrace();
// }
//
// TransformerFactory tf = TransformerFactory.newInstance();
// // 此实例可以用于处理来自不同源的 XML,并将转换输出写入各种接收器。
// Transformer transformer;
// OutputStreamWriter pw = null;
// try {
// transformer = tf.newTransformer();
// // 创建带有 DOM 节点的新输入源
// JDOMSource source = new JDOMSource(doc);
// // 设置转换中实际的输出属性
// transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
// // 设置转换中实际的输出属性
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// // 编码方式
// pw = new OutputStreamWriter(new FileOutputStream(filePath), "UTF-8");
// // 从字节流构造 StreamResult
// StreamResult result = new StreamResult(pw);
// // 充当转换结果的持有者,可以为
// // XML、纯文本、HTML
// // 或某些其他格式的标记
// // 将 XML Source 转换为 Result
// transformer.transform(source, result);
// // 关闭流
// }
// catch (Exception ex) {
// Logger.getLogger(WriteXML.class.getName()).log(Level.SEVERE, null, ex);
// }
// finally {
// if (pw != null) {
// try {
// pw.close();
// }
// catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
}
/**
* 递归Document树:找出满足条件的节点
*
* @param nodeEl
* 当前节点
* @param tagName
* 标签名字
* @param text
* 文本内容
* @param XMLNodeList
* 存储满足条件节点的容器
* @return boolean 是否结束
*/
@SuppressWarnings("unchecked")
public boolean recureDocument(Element nodeEl, String tagName, String text, List<XMLNode> XMLNodeList) {
// 判断是否到了解析终止点
boolean breakPoint = checkBreakPoint(nodeEl, tagName, text);
// 如果到了终止点
if (breakPoint) {
// 自定义接口的直接终止,否则根据解析过滤规则判断是否能够终止
if (xmlParserHandler != null || endDocument(nodeEl, XMLNodeList)) {
return true;
}
}
// 没有的话继续递归后续子节点
else {
// 得到根元素所有子元素的集合
List<Element> nodeList = nodeEl.getChildren();
if (nodeList != null && nodeList.size() > 0) {
for (Element ele : nodeList) {
if (recureDocument(ele, tagName, text, XMLNodeList)) {
return true;
}
}
}
}
return false;
}
/**
* 检测是否到了解析终止点
*
* @param nodeEl
* 当前节点
* @param tagName
* 标签名字
* @param text
* 文本内容
* @return 是否终止点
*/
private boolean checkBreakPoint(Element nodeEl, String tagName, String text) {
boolean breakPoint = false;
// 自定义xml解析接口
if (xmlParserHandler != null) {
breakPoint = xmlParserHandler.parserElementNode(nodeEl);
}
// 查询某些特殊节点
else {
boolean tag = tagName == null ? false : true;
// 查询节点的方式,tag or text,根据名字匹配规则判断是否找到了节点
if (tag && tagName.equals(nodeEl.getName()) || !tag && text.equals(nodeEl.getText())) {
breakPoint = true;
}
}
return breakPoint;
}
/**
* 添加一个XMLNode,并且判断是否已经完成
*
* @param root
* Element节点
* @return XMLNode
*/
@SuppressWarnings("unchecked")
private boolean endDocument(Element root, List<XMLNode> XMLNodeList) {
boolean end = false;
XMLNode node = new XMLNode(root.getName(), root.getText());
List<Attribute> list = root.getAttributes();
if (list != null && list.size() > 0) {
for (Attribute attribute : list) {
node.getAttribute().add(new XMLNode(attribute.getName(), attribute.getValue()));
}
}
// 是否要获取唯一节点
if (isOnly) {
if (judgementBasis.equals(JUDGEMENT_BASIS_TYPE1)) {
if (root.getText() != null && !root.getText().equals("")) {
XMLNodeList.add(node);
end = true;
}
}
else if (judgementBasis.equals(JUDGEMENT_BASIS_TYPE2)) {
if (root.getText() == null || root.getText().equals("")) {
XMLNodeList.add(node);
end = true;
}
}
else if (judgementBasis.equals(JUDGEMENT_BASIS_TYPE3)) {
if (root.getAttributes() != null && root.getAttributes().size() > 0) {
XMLNodeList.add(node);
end = true;
}
}
else if (judgementBasis.equals(JUDGEMENT_BASIS_TYPE4)) {
if (root.getAttributes() == null || root.getAttributes().size() == 0) {
XMLNodeList.add(node);
end = true;
}
}
}
else {
XMLNodeList.add(node);
}
return end;
}
public void setRefresh(boolean refresh) {
this.refresh = refresh;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
// public static void main(String[] args) {
// System.out.println(new
// ReadXML(ReadXML.JUDGEMENT_BASIS_TYPE3).getTextContentByTagFromFile("D:\\test.xml",
// "第一层节点"));
// System.out.println(new
// ReadXML().getTextContentByTagFromFile("D:\\test.xml", "第二层节点"));
// XMLNode node = new
// ReadXML(ReadXML.JUDGEMENT_BASIS_TYPE3).getXMLNodeByTagFromFile("D:\\test.xml",
// "第一层节点");
// System.out.println(node.getAttribute().get(0).getTagName());
// System.out.println(node.getAttribute().get(0).getTextValue());
// List<XMLNode> list = new ReadXML().getXMLNodeListByTagFromFile(
// "D:\\test.xml", "第二层节点");
// if (list != null && list.size() > 0) {
// for (XMLNode nodeItem : list) {
// System.out.println("节点名字:" + nodeItem.getTagName());
// System.out.println("节点值:" + nodeItem.getTextValue());
// List<XMLNode> attribute = nodeItem.getAttribute();
// for (XMLNode item : attribute) {
// System.out.println("属性名字:" + item.getTagName());
// System.out.println("属性值:" + item.getTextValue());
// }
// }
// }
// }
}
package com.epoint.utility.xml;
import java.util.ArrayList;
import java.util.List;
/**
* XML节点对象
*
* @author komojoemary
* @version [版本号, 2010-11-17]
*/
public class XMLNode
{
/**
* 标签名字
*/
private String tagName = null;
/**
* 文本值
*/
private String textValue = null;
/**
* 属性列表
*/
private List<XMLNode> attribute;
/**
* 子节点列表
*/
private List<XMLNode> children;
public XMLNode() {
}
/**
* 构造函数
*
* @param tagName
* 标签名字
* @param textValue
* 标签值
*/
public XMLNode(String tagName, String textValue) {
super();
this.tagName = tagName;
this.textValue = textValue;
}
/**
* 构造函数
*
* @param tagName
* 标签名字
* @param textValue
* 标签值
* @param attributeName
* 属性名字
* @param attributeValue
* 属性值
*/
public XMLNode(String tagName, String textValue, String attributeName, String attributeValue) {
super();
this.tagName = tagName;
this.textValue = textValue;
if (attributeName != null && !attributeName.equals("")) {
getAttribute().add(new XMLNode(attributeName, attributeValue));
}
}
/**
* 添加属性
*
* @param attribute
* 属性节点对象
*/
public void addAttribute(XMLNode attribute) {
getAttribute().add(attribute);
}
/**
* 添加子节点
*
* @param childNode
* 子节点对象
*/
public void addChildNode(XMLNode childNode) {
getChildren().add(childNode);
}
/**
* 添加子节点(返回添加的子节点对象)
*
* @param tagName
* 标签名字
* @param textValue
* 标签值
* @return XMLNode
*/
public XMLNode addChildNode(String tagName, String textValue) {
XMLNode node = new XMLNode(tagName, textValue);
getChildren().add(node);
return node;
}
public String getTagName() {
return tagName;
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
public String getTextValue() {
return textValue;
}
public void setTextValue(String textValue) {
this.textValue = textValue;
}
public List<XMLNode> getAttribute() {
if (attribute == null) {
attribute = new ArrayList<XMLNode>();
}
return attribute;
}
public void setAttribute(List<XMLNode> attribute) {
this.attribute = attribute;
}
public List<XMLNode> getChildren() {
if (children == null) {
children = new ArrayList<XMLNode>();
}
return children;
}
public void setChildren(List<XMLNode> children) {
this.children = children;
}
/**
* 是否叶子节点
*
* @return boolean
*/
public boolean isLeaf() {
return getChildren().size() == 0 ? true : false;
}
}
原文出处 http://www.cnblogs.com/komojoemary/archive/2011/11/06/xmlParser.html
package com.epoint.utility.xml;
import org.jdom.Element;
/**
* xml解析自定义接口,用于比较复杂的xml解析,实现自己的特定业务逻辑
*
* @作者 komojoemary
* @version [版本号, 2011-7-4]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public interface XmlParserHandler
{
/**
* 解析xml dom tree 节点
*
* @param nodeEl
* 某个节点
* @return 是否结束解析
*/
public boolean parserElementNode(Element nodeEl);
}