本文分为两种方式:
方式一:修改读入的xml文档结构
方式二:中规中矩,在字符流读取的时候进行判断取值。
方式一:
读取xml中的键值对存放在map<String,Object>中
首先读取xml文档,将xml文档转成便于解析的结构,
使用"}"替代</*>,作为结束符,即<key>value</key>转换为{key=value}
package club.reed.collection.xmlToMap;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class Utils {
public static Map xmlToMap(String path) throws IOException {
//通过路径获取xml文档内容
String xmlContent = getXmlContent(path);
return xmlPraser(xmlContent);
}
private static String getXmlContent(String s) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(new File(s)));
StringBuilder stringBuilder = new StringBuilder();
int read = reader.read();
while (read!=-1){
stringBuilder.append((char)read+reader.readLine());
read = reader.read();
}
return stringBuilder.toString();
}
public static Map xmlPraser(String xmlContent){
//去除注释,换格式
String s = xmlContent.replaceAll("<!--((?!<!--).).*-->", "")
.replaceAll("<((?!<).)+/>","")
.replaceAll("<\\?((?!<).)+\\?>","")
.replaceAll("> *<","><")
.replaceAll("[\r\n]","")
.replaceAll("</((?!<).)+>","}")
.replaceAll(">","=")
.replaceAll("<","{");
System.out.println(s);
HashMap<String,Object> map = new HashMap<>();
praser(s.toCharArray(),0,map);
return map;
}
public static int praser(char[] chars,int i,Map map){
for(;i<chars.length;i++){
if(i==chars.length-1)return i;
if(chars[i]=='}'){
if(chars[++i]=='{'){
i--;
continue;
}else if(chars[i]=='}')return i;
}
if(chars[i]=='{'){
String temp = getStringFromIndexToChar(chars, i+1, '=');
//System.out.println(temp);
i+=temp.length()+2;
if(chars[i]!='{'){
String value = getStringFromIndexToChar(chars, i, '}');
//System.out.println(temp+" "+value);
map.put(temp,value);
}else{
HashMap<String,Object> next = new HashMap<>();
map.put(temp,next);
//System.out.println(temp);
i=praser(chars,i,next);
}
}
}
return i;
}
public static String getStringFromIndexToChar(char[] chars,int i,char c){
StringBuilder string = new StringBuilder();
while(chars[i]!=c){
string.append(chars[i]);
i++;
}
return string.toString();
}
}
方式二:
在读入字符的时候判断取值。
package com.reed.xmlToMap;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class XmlToMapUtils {
public static BufferedReader getXmlReader(String path){
try {
return new BufferedReader(new FileReader(new File(path)));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
public static Map praser(BufferedReader reader,Map map,int tmp) throws IOException {
int read;
if(tmp==-2){
read = reader.read();
}else read = tmp;
char temp;
while(read!=-1){
temp = (char)read;
//跳过标签间隔空白,换行,回车
if(read=='\r'||read=='\n'||read==' ')
temp = (char)skipEmpty(reader);
if(temp=='<'){
String key = getStringFromIndexToChar(reader,'>');
//返回上一层
if(key.startsWith("/"))return map;
//检查是否为正确的key
if(checkIsKey(key)) {
temp =(char)skipEmpty(reader);
if(temp!='<'){
String value = getStringFromIndexToChar(reader,'<');
map.put(key,temp+value);
skipToGivenChar(reader,'>');
}else{
HashMap<String,Object> next = new HashMap<>();
map.put(key,next);
praser(reader,next,temp);
}
}
}
read = skipEmpty(reader);
}
return map;
}
//跳到指定的字符
private static void skipToGivenChar(BufferedReader reader,char c) throws IOException {
int temp = reader.read();
while(temp!=-1&&(char)temp!=c){
temp = reader.read();
}
}
//检查获取的key是否符合标准
private static boolean checkIsKey(String string) {
if(string.startsWith("?")&&string.endsWith("?"))return false;
if(string.endsWith("/"))return false;
if(string.startsWith("!--")&&string.endsWith("--"))return false;
return true;
}
//获取到下一个给出字符的字符串
private static String getStringFromIndexToChar(BufferedReader reader, char c) throws IOException {
int read = reader.read();
StringBuilder string = new StringBuilder();
while (read!=-1&&(char)read!=c){
if((char)read!='\r'&&(char)read!='\n')
string.append((char)read);
read = reader.read();
}
return string.toString();
}
//跳过空白换行回车
public static int skipEmpty(BufferedReader reader) throws IOException {
int read = reader.read();
while((read=='\r'||read=='\n'||read==' ')&&read!=-1) {
read = (char) reader.read();
}
return read;
}
}