xml字符串转字符串树

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.Stack;

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

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

/**
  *将xml字符串转成树结构,此类所在包下应该放置一个名为string的文件,文件内容为xml格式字符串<br>
  * 
  * 
 字符串<br>
 <operation_in><service_name></service_name><verify_code/><request_type/><sysfunc_id>10010082</sysfunc_id><trans_code/><operator_id/><organ_id>1000</organ_id><request_time/><request_seq/><request_source>100001</request_source><request_target>200001</request_target><msg_version>0100</msg_version><cont_version>0100</cont_version><content><field><name>ActionCode</name><id>0</id><simple>QUERYOFFER</simple></field><field><name>Mobile</name><id>0</id><simple>15210939334</simple></field><field><name>Source</name><id>0</id><simple>WEB3</simple></field><field><name>UserTime</name><id>0</id><simple>09/06/2015 16:58:24</simple></field><field><name>FIELD1</name><id>0</id><simple>111002000047</simple></field></content></operation_in>
的转换结果为<br>
operation_in
|       
|-------service_name······························<br>
|       
|-------verify_code·······························<br>
|       
|-------request_type······························<br>
|       
|-------sysfunc_id································10010082<br>
|       
|-------trans_code································<br>
|       
|-------operator_id·······························<br>
|       
|-------organ_id··································1000<br>
|       
|-------request_time······························<br>
|       
|-------request_seq·······························<br>
|       
|-------request_source····························100001<br>
|       
|-------request_target····························200001<br>
|       
|-------msg_version·······························0100<br>
|       
|-------cont_version······························0100<br>
|       
|-------content<br>
|       |       
|       |-------field<br>
|       |       |       
|       |       |-------name······················ActionCode<br>
|       |       |       
|       |       |-------id························0<br>
|       |       |       
|       |       |-------simple····················QUERYOFFER<br>
|       |       
|       |-------field<br>
|       |       |       
|       |       |-------name······················Mobile<br>
|       |       |       
|       |       |-------id························0<br>
|       |       |       
|       |       |-------simple····················15210939334<br>
|       |       
|       |-------field<br>
|       |       |       
|       |       |-------name······················Source<br>
|       |       |       
|       |       |-------id························0<br>
|       |       |       
|       |       |-------simple····················WEB3<br>
|       |       
|       |-------field<br>
|       |       |       
|       |       |-------name······················UserTime<br>
|       |       |       
|       |       |-------id························0<br>
|       |       |       
|       |       |-------simple····················09/06/2015 16:58:24<br>
|       |       
|       |-------field<br>
|       |       |       
|       |       |-------name······················FIELD1<br>
|       |       |       
|       |       |-------id························0<br>
|       |       |       
|       |       |-------simple····················111002000047<br>

 */
public class Main {

	final static String depthStr="|       ";
	final static String nodeStr="|-------";
	final static String line="\n";
	final static char valueSpliter='·';
	final static int VALUE_START_POSITION=33;//调节显示节点值的位置
	
	public static void main(String[] args) throws IOException {
		//此类所在的包下有一个名叫string的文件,里面存放xml格式的报文
		InputStream stream=Main.class.getClassLoader().getResourceAsStream("cn/com/lewis/xml2tree/string");
		BufferedReader br=null;
		try {
			br = new BufferedReader(new InputStreamReader(stream,"GBK"));
			StringBuilder builder=new StringBuilder();
			String tmp=null;
			while((tmp=br.readLine())!=null){
				builder.append(tmp);
			}
			System.out.println(xmlToTree(builder.toString()));
		} catch (IOException | ParserConfigurationException | SAXException e1) {
			e1.printStackTrace();
		}finally{
			if(br!=null){
				br.close();
			}
			
		}
	}
	
	
	
	/**
	 * 转换函数,非递归方式的实现
	 * @param document
	 * @return
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * @throws SAXException 
	 */
	public static String xmlToTree(String reqStr) throws ParserConfigurationException, SAXException, IOException{
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		StringReader sr = new StringReader(reqStr);
		Document document=db.parse(new InputSource(sr));
		Element root=document.getDocumentElement();
		NodeList iterator=root.getChildNodes();
		Stack<StackItem<Integer>> stack=new Stack<StackItem<Integer>>();
		int j=0;
		StringBuilder builder=new StringBuilder(root.getNodeName()+line);
		Integer depth=0;//此处必须是对象,因为泛型要取匹配类型
		do{
			for(;j<iterator.getLength();j++){
				Node childNode = iterator.item(j);
				if(childNode.getNodeType() == Node.ELEMENT_NODE){
					StringBuilder tmpBuilder=new StringBuilder();
					for(int ii=0;ii<depth;++ii){
						builder.append(depthStr);
						tmpBuilder.append(depthStr);
					}	
					builder.append(depthStr).append(line).append(tmpBuilder).append(nodeStr).append(childNode.getNodeName());
					if(childNode.getChildNodes().getLength()==0||
							(childNode.getChildNodes().getLength()==1&&childNode.getChildNodes().item(0).getNodeType() != Node.ELEMENT_NODE) ){
						int chc=depthStr.length()*depth+nodeStr.length()+childNode.getNodeName().length();
						for(int ii=0;ii<VALUE_START_POSITION-chc;++ii){
							builder.append(valueSpliter);
						}
						builder.append("示例值:").append(childNode.getTextContent());
					}else{
						stack.push(new StackItem<Integer>(iterator,j+1,depth));
						depth=new Integer(depth.intValue()+1);//防止编译时优化成对象自增
						j=-1;//j++后值变成0,获取下级节点的首子节点
						iterator=childNode.getChildNodes();
					}
					builder.append(line);
				}	
			}
			
			if(stack.isEmpty()){
				break;
			}
			StackItem<Integer> topItem=stack.pop();
			iterator=topItem.iterator;
			j=topItem.index;
			depth=topItem.cacheObject;
		}while(true);
		return builder.toString();
	}
	
	/**
	 * 
	 *
	 * @param <T>
	 */
	static class StackItem<T> {
		
		/**
		 * 迭代到的xml节点
		 */
		public NodeList iterator;
		
		/**
		 * 迭代到的序号
		 */
		public int index;
		
		/**
		 * 附加的数据
		 */
		public T cacheObject;

		public StackItem(NodeList iterator, int index, T cacheObject) {
			super();
			this.iterator = iterator;
			this.index = index;
			this.cacheObject = cacheObject;
		}

		public StackItem() {
			super();
		}	
	}
	
}

猜你喜欢

转载自blog.csdn.net/qq631431929/article/details/48447071