属性值不支持空格 package httpclient; import java.io.*; import java.util.ArrayList; import java.util.HashMap; class ParseException extends Exception{ public ParseException(String message) { super(message); } } class RInputStream extends InputStream{ Integer buffer; private InputStream in; public RInputStream(InputStream in) { this.in = in; } public void returnChar(char c){ buffer=(int)c; } @Override public int read() throws IOException { if(buffer!=null){ int tmp= buffer; buffer=null; return tmp; }else{ return in.read(); } } } public class XmlUtil { public static void error(String str){ System.out.println(str); } public static Element parse(RInputStream in) throws IOException { char c; int a; boolean init=true; while((a=in.read())!=-1){ c=(char)a; if(init){ if(space(c)){ continue; }else if(c!='<'){ error("最开始字符需要<!"); return null; }else{ init=false; } }else{ if(space(c)){ continue; }else if(c=='<'){ error("头行两个<!"); }else if(c=='>'){ break; } } } c = firstNonNull(in); if(c!='<') { error("需要< 但是发现" + c); return null; } Element element = null; try { element = parseBody(in); } catch (ParseException e) { error(e.getMessage()); } catch (IOException e) { error(e.getMessage()); } in.close(); return element; } public static Element parseBody(RInputStream in) throws ParseException,IOException{ boolean leaveBegin=false; boolean gotEleName=false; boolean gettingEleName=false; boolean gettingValue=false; boolean isPlainValue=false; boolean gotAttrName=false; boolean gettingAttrName=false; boolean gotEq=false; boolean gettingAttrValue=false; boolean spaceArrowGenerateAttrHadStore=true; char c; int a; StringBuilder eleName = new StringBuilder(); ArrayList<Object> value = new ArrayList<Object>(); StringBuilder plainValue = new StringBuilder(); HashMap<String, String> attributes = new HashMap<String, String>(); StringBuilder attrName = new StringBuilder(); StringBuilder attrValue = new StringBuilder(); Element N = new Element(null, null, null); while((a=in.read())!=-1){ c=(char)a; if(leaveBegin){ if(gettingValue){ if(isPlainValue){ if(space(c)){ if(firstNonNull(in)!='<'){ throw new ParseException("已获取元素值但出现了"+c); }else{ if(firstNonNull(in)!='/'){ throw new ParseException("已获取元素值但出现了<"+c); }else{ String endEleName = parseEnd(in); if(!eleName.toString().equals(endEleName)){ throw new ParseException("前后eleName不同"+eleName.toString()+" "+endEleName); }else{ break; } } } }else if(c=='>'){ throw new ParseException("正在获取字符串元素值但出现了>"); }else if(c=='<'){ if(firstNonNull(in)!='/'){ throw new ParseException("已获取元素值但出现了<"+c); }else{ String endEleName = parseEnd(in); if(!eleName.toString().equals(endEleName)){ throw new ParseException("前后eleName不同"+eleName.toString()+" "+endEleName); }else{ break; } } }else{ plainValue.append(c); } }else{//是元素值 if(space(c)){ continue; }else if(c!='<'){ throw new Error("正在获取元素子元素值但出现了"+c); }else{ c=firstNonNull(in); if(c=='/'){ String endEleName = parseEnd(in); if(!eleName.toString().equals(endEleName)){ throw new ParseException("前后eleName不同"+eleName.toString()+" "+endEleName); }else{ break; } }else{ in.returnChar(c); Element subElementN = parseBody(in); value.add(subElementN); } } } }else{// 未正在获取值 if(space(c)){ continue; }else if(c=='>'){ throw new ParseException("将要获取元素值但出现了>"); }else if(c=='<'){ c=firstNonNull(in); if(c=='/'){ String endEleName = parseEnd(in); if(!eleName.toString().equals(endEleName)){ throw new ParseException("前后eleName不同"+eleName.toString()+" "+endEleName); }else{ break; } }else{ in.returnChar(c); Element subElement = parseBody(in); value.add(subElement); gettingValue=true; } }else{ plainValue.append(c); gettingValue=true; isPlainValue=true; } } }else { //未离开开始标签 if(gotEleName){//已获取eleName if(gettingAttrName){ if(gotAttrName){ if(gotEq){ if(gettingAttrValue){ if(space(c)){ gotAttrName=false; gettingAttrName=false; gettingAttrValue=false; gotEq=false; spaceArrowGenerateAttrHadStore=true; attributes.put(attrName.toString(),attrValue.toString()); attrName.delete(0,attrName.length()); attrValue.delete(0,attrValue.length()); }else if(c=='<'){ throw new ParseException("正在获取属性值 但是出现了<"); }else if(c=='>'){ if(!spaceArrowGenerateAttrHadStore) attributes.put(attrName.toString(),attrValue.toString()); leaveBegin=true; }else{ attrValue.append(c); } }else{//未正在获取属性值 if(space(c)){ continue; }else if(c=='<' || c=='>'){ throw new ParseException("未获取属性值但出现了"+c); }else{ attrValue.append(c); gettingAttrValue=true; } } }else{//未获取Eq if(space(c)){ continue; }else if(c=='<' || c=='>'){ throw new ParseException("已获取属性名未获取属性值,但出现了"+c); }else if (c!='='){ throw new ParseException("以获取属性名 需要= 但出现了"+c); }else{ gotEq=true; } } }else{//未获取属性名 if(space(c)){ gotAttrName=true; }else if(c=='='){ gotAttrName=true; gotEq=true; }else if(c=='<'|| c=='>'){ throw new ParseException("正在获取属性 未获取属性名 但是出现了"+c); }else{ attrName.append(c); } } }else{//未正在获取属性 if(space(c)){ continue; }else if(c=='<'){ throw new ParseException("已获取eleName,需要结束标签,但是发现了<"); }else if(c=='>'){ leaveBegin=true; }else { spaceArrowGenerateAttrHadStore=false; attrName.append(c); gettingAttrName=true; } } }else{ //未获取eleName if(gettingEleName){//正在获取eleName if(space(c)){ gotEleName=true; }else{ if(c=='<'){ throw new ParseException("正在获取eleName 但出现了"+c); }else if (c=='>'){ leaveBegin=true; }else{ eleName.append(c); } } }else{//未正在获取eleName if (space(c)){ continue; }else{ if(c=='<' || c=='>'){ throw new ParseException("尚未开始获取eleName 但出现了"+c); }else{ eleName.append(c); gettingEleName=true; } } } } } } N.setElementName(eleName.toString()); N.setAttributes(attributes); N.setPlainValue(isPlainValue); if(isPlainValue) N.setValue(plainValue.toString()); else N.setValue(value); return N; } public static char firstNonNull(RInputStream in) throws IOException { int a; char c=' '; while((a=in.read())!=-1){ c=(char)a; if(space(c)){ continue; }else{ return c; } } return c; } public static String parseEnd(InputStream in) throws ParseException,IOException{ boolean gettingEndEleName=false; boolean gotEndEleName=false; StringBuilder eleName = new StringBuilder(); char c; int a; while((a=in.read())!=-1){ c=(char)a; if(gotEndEleName){ if(space(c)){ continue; }else if (c!='>'){ throw new ParseException("需要> d但发现"+c); }else return eleName.toString(); }else{ if(gettingEndEleName){ if(space(c)){ gotEndEleName=true; }else if(c=='<'){ throw new ParseException("两个连续的<"); }else if(c=='>'){ return eleName.toString(); }else eleName.append(c); }else{ if (space(c)){ continue; }else if(c=='>' || c=='<'){ throw new ParseException("未获取到eleName 获取< , >已经结束"); }else{ eleName.append(c); gettingEndEleName=true; } } } } return eleName.toString(); } public static boolean space(char c){ if( c=='\t' ||c=='\n' || c=='\r'|| c==' '){ return true; } return false; } public static void main(String[] args) throws IOException { Element element = parse(new RInputStream(XmlUtil.class.getResourceAsStream("/pom.xml"))); element.print(null); } }
package httpclient; import java.util.HashMap; import java.util.List; public class Element { private String elementName; private Object value; private HashMap<String,String> attributes; private boolean isPlainValue; public boolean isPlainValue() { return isPlainValue; } public void setPlainValue(boolean plainValue) { isPlainValue = plainValue; } public Element(String elementName, Object value, HashMap<String, String> attributes) { this.elementName = elementName; this.value = value; this.attributes = attributes; } Element getChildByName(String childName){ if(!isPlainValue){ List<Element> value = (List<Element>) this.value; for(Element ele:value){ if(ele.getElementName().equals(childName)){ return ele; } } } return null; } public void print(Integer i){ if(i==null) i=0; indentation(i,this.elementName); if(!this.attributes.isEmpty()) indentation(i,this.attributes.toString()); if(isPlainValue) indentation(i,this.value.toString()); else{ List<Element> list = (List<Element>) this.value; for(int m=0;m<list.size();m++){ list.get(m).print(i+1); if(m!=list.size()-1) indentation(i+1,"-------------"); } } } private void indentation(int i,String string){ int j=i; while(j--!=0)System.out.print('\t'); System.out.println(string); } public String getElementName() { return elementName; } public void setElementName(String elementName) { this.elementName = elementName; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public HashMap<String, String> getAttributes() { return attributes; } public void setAttributes(HashMap<String, String> attributes) { this.attributes = attributes; } }