获取XML的XPATH - JAVA

XmlErgodicTool.java实现了获取XML的XPATH,并且可以根据需要过滤属性的关键字。


List<String> attrFilter = new ArrayList<String>();


attrFilter.add("name");

 

 

1. XmlErgodicTool.java

 

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * 
 * 
 * 
 * <DL>
 * <DT><B> 递归遍历XML所有叶子节点的XPATH-JAVA </B></DT>
 * <p>
 * <DD>详细介绍</DD>
 * </DL>
 * <p>
 * 
 * <DL>
 * <DT><B>使用范例</B></DT>
 * <p>
 * <DD>使用范例说明</DD>
 * </DL>
 * <p>
 * 
 * @author 周典
 * @version
 * @Date: 2011-3-7 下午上午11:41:46
 */
public class XmlErgodicTool {

	/** XML编码 */
	private String encoding = "utf-8";

	/**
	 * @return the encoding
	 */
	public String getEncoding() {
		return encoding;
	}

	/**
	 * @param encoding
	 *            the encoding to set
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	/**
	 * 
	 * 
	 * <DL>
	 * <DT><B> 标题 </B></DT>
	 * <DD>详细介绍</DD>
	 * </DL>
	 * 
	 * 
	 */
	public XmlErgodicTool() {

	}

	/**
	 * 
	 * <DL>
	 * <DT><B> 从一个字符串中,获取XML叶子Bean的列表 </B></DT>
	 * <DD>详细介绍</DD>
	 * </DL>
	 * 
	 * @param xmlString
	 * @param attrFilter
	 * @return
	 * 
	 */
	public List<XmlLeafBean> getXmlLeafBeanList(String xmlString,
			List<String> attrFilter) {
		List<XmlLeafBean> xmlLeafBeanList = new ArrayList<XmlLeafBean>();
		Document document = null;
		try {
			// xmlString = new String(xmlString.getBytes(), encoding);
			StringReader stringReader = new StringReader(xmlString);
			InputSource inputSource = new InputSource(stringReader);
			DocumentBuilderFactory docBuilderFac = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docBuilderFac.newDocumentBuilder();
			document = docBuilder.parse(inputSource);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Node node = document.getDocumentElement();
		this.getElementList(node, xmlLeafBeanList, "", attrFilter);

		return xmlLeafBeanList;
	}

	/**
	 * 
	 * 
	 * <DL>
	 * <DT><B> 从一个文件获取XML叶子Bean的列表 </B></DT>
	 * <DD>详细介绍</DD>
	 * </DL>
	 * 
	 * @param xmlFile
	 * @param attrFilter
	 * @return
	 * 
	 */
	public List<XmlLeafBean> getXmlLeafBeanList(File xmlFile,
			List<String> attrFilter) {
		List<XmlLeafBean> xmlLeafBeanList = new ArrayList<XmlLeafBean>();
		DocumentBuilderFactory dBuilderFac = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder dBuilder = null;
		Document document = null;
		try {
			dBuilder = dBuilderFac.newDocumentBuilder();
			document = dBuilder.parse(xmlFile);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Node node = document.getDocumentElement();
		this.getElementList(node, xmlLeafBeanList, "", attrFilter);
		this.createUniqueXmlLeafBeanList(xmlLeafBeanList, null, 0, 1);
		return xmlLeafBeanList;
	}

	/**
	 * 
	 * <DL>
	 * <DT><B> 递归遍历 Node取得XPath列表</B></DT>
	 * <DD>详细介绍</DD>
	 * </DL>
	 * 
	 * @param node
	 * @param xmlLeafBeanList
	 * @param currentNode
	 * @param filter
	 * 
	 */
	private void getElementList(Node node, List<XmlLeafBean> xmlLeafBeanList,
			String currentNode, List<String> filter) {
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			currentNode = currentNode + "/" + node.getNodeName();
			NamedNodeMap namedNodeMap = node.getAttributes();
			String nodeAttr = "[ ";
			for (int i = 0; i < namedNodeMap.getLength(); i++) {
				Node attribute = namedNodeMap.item(i);
				if (filter == null || filter.size() == 0) {
					String nameAttr = " and @" + attribute.getNodeName() + "='"
							+ attribute.getNodeValue() + "'";
					nodeAttr += nameAttr;
				} else if (filter.contains(attribute.getNodeName())) {
					String nameAttr = " and @" + attribute.getNodeName() + "='"
							+ attribute.getNodeValue() + "'";
					nodeAttr += nameAttr;
				}
			}
			nodeAttr += " ]";
			if (namedNodeMap.getLength() > 0 && nodeAttr.length() > 4) {
				int indexAnd = nodeAttr.indexOf(" and ");
				nodeAttr = nodeAttr.substring(0, indexAnd)
						+ nodeAttr.substring(indexAnd + (" and ").length());
				currentNode += nodeAttr;
			}
			NodeList nodeList = node.getChildNodes();
			for (int i = 0; nodeList != null && i < nodeList.getLength(); i++) {
				this.getElementList(nodeList.item(i), xmlLeafBeanList,
						currentNode, filter);
			}
		} else if (node.getNodeType() == Node.TEXT_NODE) {
			if (!("").equals(node.getNodeValue().trim())) {
				String xpath = currentNode;
				String value = node.getNodeValue();
				xmlLeafBeanList.add(new XmlLeafBean(xpath, value));
			}
		}
	}

	/**
	 * 
	 * 
	 * <DL>
	 * <DT><B> 创建XPath唯一的XmlLeafBeanList </B></DT>
	 * <DD>详细介绍</DD>
	 * </DL>
	 * 
	 * @param xmlLeafBeanList
	 * @param preXmlLeafBean
	 * @param listIndex
	 * @param eleIndex
	 * 
	 */
	public void createUniqueXmlLeafBeanList(List<XmlLeafBean> xmlLeafBeanList,
			XmlLeafBean preXmlLeafBean, int listIndex, int eleIndex) {
		if (listIndex == xmlLeafBeanList.size()) {
			return;
		}
		XmlLeafBean currentXmlLeafBean = xmlLeafBeanList.get(listIndex);
		listIndex++;
		if (preXmlLeafBean != null) {
			String preXPath = preXmlLeafBean.getXpath();
			preXPath = preXPath.replaceAll("\\[\\d+\\]", "");
			if (preXPath.equals(currentXmlLeafBean.getXpath())) {
				preXmlLeafBean.setXpath(preXPath + "["
						+ eleIndex + "]");
				currentXmlLeafBean.setXpath(currentXmlLeafBean.getXpath() + "["
						+ (eleIndex + 1) + "]");
				eleIndex += 1;
			} else {
				eleIndex = 1;
			}
		}
		this.createUniqueXmlLeafBeanList(xmlLeafBeanList, currentXmlLeafBean,
				listIndex, eleIndex);
	}

	public static void main(String args[]) {
		List<String> attrFilter = new ArrayList<String>();
		attrFilter.add("name");

		String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
				+ "<doc>\n" + "    <person>\n" + "        <name>某人</name>\n"
				+ "        <adds>            \n"
				+ "            <add ID=\"10002\">\n"
				+ "                <BS>10002</BS>\n"
				+ "                <note>西安市太白路</note>\n"
				+ "            </add>\n" + "            <add ID=\"\">\n"
				+ "                <BS>10002</BS>\n"
				+ "                <note>空ID节点啊</note>\n"
				+ "            </add>\n" + "            <add>\n"
				+ "                <BS>10002</BS>\n"
				+ "                <note>空ID节点啊</note>\n"
				+ "            </add>\n" + "\t\t\t<add ID=\"10001\">\n"
				+ "\t\t\t\t<BS xmlns=\"10001\"/>\n"
				+ "                <note>西安市太白路2</note>\n"
				+ "            </add>\n" + "\t\t</adds>\n" + "    </person>\n"
				+ "    <other>\n" + "        <name ID=\"HEHE\">ASDF</name>\n"
				+ "    </other>\n" + "</doc>";
		XmlErgodicTool xmlErgodicTool1 = new XmlErgodicTool();
		List<XmlLeafBean> xmlLeafBeanList = xmlErgodicTool1.getXmlLeafBeanList(
				xmlString, attrFilter);
		for (XmlLeafBean xmlLeafBean : xmlLeafBeanList) {
			System.out.println(xmlLeafBean.getXpath() + " , "
					+ xmlLeafBean.getValue());
		}

		System.out.println("__________");

		XmlErgodicTool xmlErgodicTool2 = new XmlErgodicTool();
		List<XmlLeafBean> xmlLeafBeanList2 = xmlErgodicTool2
				.getXmlLeafBeanList(
						new File(
								"F:\\测试.xml"),
						attrFilter);
		for (XmlLeafBean xmlLeafBean : xmlLeafBeanList2) {
			System.out.println(xmlLeafBean.getXpath() + " , "
					+ xmlLeafBean.getValue());
		}
	}
}

 

2. XmlLeafBean.java

 

/**
 * 
 * <DL>
 * <DT><B> xml的叶子节点的Bean </B></DT>
 * <p>
 * <DD>详细介绍</DD>
 * <DD>这个Bean用来存放叶子节点的XPath 和 对应的Value</DD>
 * </DL>
 * <p>
 * 
 * <DL>
 * <DT><B>使用范例</B></DT>
 * <p>
 * <DD>使用范例说明</DD>
 * </DL>
 * <p>
 * 
 * @author 周典
 * @version
 * @Date: 2011-3-7 下午上午11:03:52
 * 
 */
public class XmlLeafBean {

	private String xpath;

	private String value;

	public XmlLeafBean() {

	}

	/**
	 * 
	 * <DL>
	 * <DT><B> 标题 </B></DT>
	 * <DD>详细介绍</DD>
	 * </DL>
	 * 
	 * @param xpath
	 * @param value
	 * 
	 */
	public XmlLeafBean(String xpath, String value) {
		this.xpath = xpath;
		this.value = value;
	}

	/**
	 * @return the xpath
	 */
	public String getXpath() {
		return xpath;
	}

	/**
	 * @param xpath
	 *            the xpath to set
	 */
	public void setXpath(String xpath) {
		this.xpath = xpath;
	}

	/**
	 * @return the value
	 */
	public String getValue() {
		return value;
	}

	/**
	 * @param value
	 *            the value to set
	 */
	public void setValue(String value) {
		this.value = value;
	}
}

 

3. 测试.xml

 

<?xml version="1.0" encoding="GB2312"?>
<service name="">
	<sys-header>
		<data name="SYS_HEAD">
			<struct>
				<data name="MESSAGE_TYPE">
					<field type="string" length="4" encrypt-mode="">1400</field>
					<field type="string" length="4" encrypt-mode="">1401</field>
					<field type="string" length="4" encrypt-mode="">1402</field>
					<field type="string" length="4" encrypt-mode="">1403</field>
					<field type="string" length="4" encrypt-mode="">1404</field>
					<field type="string" length="4" encrypt-mode="">1405</field>
				</data>
				<data name="MESSAGE_CODE">
					<field type="string" length="6" encrypt-mode="">9100</field>
					<field type="string" length="6" encrypt-mode="">9100</field>
				</data>
				<data name="SERVICE_CODE">
					<field type="string" length="8" encrypt-mode="">SVR_INQUIRY</field>
				</data>
			</struct>
		</data>
	</sys-header>
	<app-header>
		<data name="APP_HEAD">
			<struct>
				<data name="PGUP_OR_PGDN">
					<field type="string" length="1" encrypt-mode="">1</field>
				</data>
				<data name="TOTAL_NUM">
					<field type="string" length="10" encrypt-mode="">10</field>
				</data>
				<data name="CURRENT_NUM">
					<field type="string" length="10" encrypt-mode="">0</field>
				</data>
				<data name="PAGE_START">
					<field type="string" length="10" encrypt-mode="">0</field>
				</data>
				<data name="PAGE_END">
					<field type="string" length="10" encrypt-mode="">0</field>
				</data>
			</struct>
		</data>
	</app-header>
	<body>
		<data name="CLIENT_NO">
			<field type="string" length="12" encrypt-mode="">1234567890123</field>
		</data>
		<data name="GLOBAL_ID">
			<field type="string" length="25" encrypt-mode="">1234567890123456789012345</field>
		</data>
		<data name="GLOBAL_TYPE">
			<field type="string" length="3" encrypt-mode="">123</field>
		</data>
		<data name="ISS_COUNTRY">
			<field type="string" length="3" encrypt-mode="">我</field>
		</data>
	</body>
</service>

 

 

运行结果:

 

/doc/person/name , 某人
/doc/person/adds/add/BS , 10002
/doc/person/adds/add/note , 西安市太白路
/doc/person/adds/add/BS , 10002
/doc/person/adds/add/note , 空ID节点啊
/doc/person/adds/add/BS , 10002
/doc/person/adds/add/note , 空ID节点啊
/doc/person/adds/add/note , 西安市太白路2
/doc/other/name , ASDF
__________
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[1] , 1400
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[2] , 1401
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[3] , 1402
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[4] , 1403
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[5] , 1404
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_TYPE' ]/field[6] , 1405
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_CODE' ]/field[1] , 9100
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='MESSAGE_CODE' ]/field[2] , 9100
/service[ @name='' ]/sys-header/data[ @name='SYS_HEAD' ]/struct/data[ @name='SERVICE_CODE' ]/field , SVR_INQUIRY
/service[ @name='' ]/app-header/data[ @name='APP_HEAD' ]/struct/data[ @name='PGUP_OR_PGDN' ]/field , 1
/service[ @name='' ]/app-header/data[ @name='APP_HEAD' ]/struct/data[ @name='TOTAL_NUM' ]/field , 10
/service[ @name='' ]/app-header/data[ @name='APP_HEAD' ]/struct/data[ @name='CURRENT_NUM' ]/field , 0
/service[ @name='' ]/app-header/data[ @name='APP_HEAD' ]/struct/data[ @name='PAGE_START' ]/field , 0
/service[ @name='' ]/app-header/data[ @name='APP_HEAD' ]/struct/data[ @name='PAGE_END' ]/field , 0
/service[ @name='' ]/body/data[ @name='CLIENT_NO' ]/field , 1234567890123
/service[ @name='' ]/body/data[ @name='GLOBAL_ID' ]/field , 1234567890123456789012345
/service[ @name='' ]/body/data[ @name='GLOBAL_TYPE' ]/field , 123
/service[ @name='' ]/body/data[ @name='ISS_COUNTRY' ]/field , 我

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在键盘上跳舞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值