Myhandler继承自DefaultHandler
主要函数:
public void startElement(String uri, String localName, String qName,
Attributes attributes)
public void startDocument()
public void endElement(String uri, String localName, String qName)
public void endDocument()
public void characters(char[] ch, int start, int length)
属性集合中获取属性名和属性值
http://book.51cto.com/art/201107/279379.htm
attribute.getvalue(i)
attribute.getname(i)
主要函数
1 class MyHandler extends DefaultHandler { 2 3 4 private String tag=""; 5 private String value=""; 6 private String currentName=""; 7 private StringBuffer str=new StringBuffer(); 8 private Properties props; 9 10 private Rule rule=null; 11 private List<Rule> rules=null; 12 13 14 public MyHandler(){ 15 this.props=new Properties(); 16 this.rules=new ArrayList<Rule>(); 17 } 18 public StringBuffer getstr() 19 { 20 return str; 21 } 22 public Properties getprops(){ 23 return props; 24 } 25 @Override 26 public InputSource resolveEntity(String publicId, String systemId) 27 throws IOException, SAXException { 28 return super.resolveEntity(publicId, systemId); 29 } 30 /* 31 * 接收注释声明事件的通知。 32 * 参数意义如下: 33 * name - 注释名称。 34 * publicId - 注释的公共标识符,如果未提供,则为 null。 35 * systemId - 注释的系统标识符,如果未提供,则为 null。 36 */ 37 @Override 38 public void notationDecl(String name, String publicId, String systemId) 39 throws SAXException { 40 super.notationDecl(name, publicId, systemId); 41 } 42 43 /* 44 * 接收未解析的实体声明事件的通知。 45 * 参数意义如下: 46 * name - 未解析的实体的名称。 47 * publicId - 实体的公共标识符,如果未提供,则为 null。 48 * systemId - 实体的系统标识符。 49 * notationName - 相关注释的名称。 50 */ 51 @Override 52 public void unparsedEntityDecl(String name, String publicId, 53 String systemId, String notationName) throws SAXException { 54 super.unparsedEntityDecl(name, publicId, systemId, notationName); 55 } 56 57 /* 58 * 接收用来查找 SAX 文档事件起源的对象。 59 * 参数意义如下: 60 * locator : 可以返回任何 SAX 文档事件位置的对象 61 */ 62 @Override 63 public void setDocumentLocator(Locator locator) { 64 super.setDocumentLocator(locator); 65 } 66 67 //一般将正式解析前的一些初始化工作放到这里面,收尾工作放在endDocument中 68 @Override 69 public void startDocument() throws SAXException { 70 System.err.println("开始解析文档"); 71 } 72 //接受文档结尾的通知 73 @Override 74 public void endDocument() throws SAXException { 75 System.err.println("解析结束"); 76 } 77 78 @Override 79 public void startPrefixMapping(String prefix, String uri) 80 throws SAXException { 81 super.startPrefixMapping(prefix, uri); 82 } 83 84 //结束前缀URI范围的映射 85 @Override 86 public void endPrefixMapping(String prefix) throws SAXException { 87 super.endPrefixMapping(prefix); 88 } 89 90 /* 91 * 接收元素开始的通知。 92 * XML解析器遇到XML里面的tag时就会调用这个函数。经常在这个函数内是通过localName俩进行判断而操作一些数据。 93 * 参数意义如下: 94 * uri :元素的命名空间 95 * localName :元素的本地名称(不带前缀) 96 * qName :元素的限定名(带前缀) 97 * attributes :元素的属性集合 98 */ 99 100 @Override 101 public void startElement(String uri, String localName, String qName, 102 Attributes attributes) throws SAXException { 103 System.out.print(" "+"Element: " + qName + ", attr: "); 104 //print(attributes); 105 int i=attributes.getLength(); 106 for(int j=0;j<i;j++) 107 { 108 String strName=attributes.getLocalName(j); 109 String strValue=attributes.getValue(j); 110 System.out.println(strName+":"+strValue); 111 } 112 this.currentName=qName; 113 } 114 115 /* 116 * @接受元素尾部通知(non-Javadoc) 117 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) 118 * @uri 元素命名空间 119 * @localName 元素本地名称 120 * @qName 元素限定名 121 */ 122 123 @Override 124 public void endElement(String uri, String localName, String qName) 125 throws SAXException { 126 super.endElement(uri, localName, qName); 127 //props.put(qName.toLowerCase(), currentName.toString().trim()); 128 } 129 130 /*接受字符数据的通知 131 * 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue) 132 * 碰到节点开始和结束之间的字符 133 * 回调方法。解析器执行完startElement()后,解析完节点的内容后就会执行这个方法,并且参数ch[]就是节点的内容。 134 */ 135 @Override 136 public void characters(char[] ch, int start, int length) 137 throws SAXException { 138 //super.characters(ch, start, length); 139 this.str.append(ch,start,length); 140 } 141 142 @Override 143 public void ignorableWhitespace(char[] ch, int start, int length) 144 throws SAXException { 145 super.ignorableWhitespace(ch, start, length); 146 } 147 148 //接受处理指令的通知 149 150 @Override 151 public void processingInstruction(String target, String data) 152 throws SAXException { 153 super.processingInstruction(target, data); 154 } 155 156 /* 157 * 接收跳过的实体的通知。 158 * 参数意义如下: 159 * name : 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头, 160 * 如果它是外部 DTD 子集,则将是字符串 "[dtd]" 161 */ 162 @Override 163 public void skippedEntity(String name) throws SAXException { 164 super.skippedEntity(name); 165 } 166 167 168 /* 169 * 接收warning的通知。 170 */ 171 @Override 172 public void warning(SAXParseException e) throws SAXException { 173 super.warning(e); 174 } 175 176 /* 177 * 接收可恢复的错误的通知 178 */ 179 @Override 180 public void error(SAXParseException e) throws SAXException { 181 super.error(e); 182 } 183 184 /* 185 * 接收不可恢复的错误的通知。 186 */ 187 @Override 188 public void fatalError(SAXParseException e) throws SAXException { 189 super.fatalError(e); 190 } 191 192 private void print(Attributes attrs) { 193 if (attrs == null) return; 194 System.err.print("["); 195 for (int i = 0; i < attrs.getLength(); i++) { 196 System.err.print(attrs.getQName(i) + " = " + attrs.getValue(i)); 197 if (i != attrs.getLength() - 1) { 198 System.err.print(", "); 199 } 200 } 201 System.err.println("]"); 202 } 203 }
XML文件
<?xml version="1.0" encoding="UTF-8"?> <rules> <message name="高度"> <part name="heigth" type="xs:integer"/> </message> <message name="长度"> <part name="length" type="xs:integer"/> </message> <message name="结果"> <part name="result" type="xs:string"/> </message> <services name="规则1"> <operation name="高度判断"> <optlist> <input message="heigth" opt="大于" baseValue="30"/> <output message="heigth" Value="高度过高" /> </optlist> <optlist> <input message="heigth" opt="大于" baseValue="20"/> <input message="heigth" opt="小于" baseValue="30"/> <output message="heigth" Value="高度合适" /> </optlist> <optlist> <input message="heigth" opt="小于" baseValue="20"/> <output message="heigth" Value="高度偏低" /> </optlist> </operation> </services> </rules>
自己写的解析程序
public class TestSAX extends DefaultHandler{ public static void main(String[] args) { read(); write(); } private String strOperationtag=""; private String strMessageName=""; private String strOptName=""; private String strBaseValue=""; private String value="28"; private boolean tag; private int signtag; private String currentName=""; private StringBuffer str=new StringBuffer(); private Rule rule=null; private List<Rule> rules=null; public static void read() { try { // 得到SAX解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //创建解析器 SAXParser parser = factory.newSAXParser(); //获得输入流 InputStream in = TestSAX.class.getClassLoader().getResourceAsStream("test.xml"); //开始解析 parser.parse(in, new TestSAX()); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void write() { System.err.println("纯SAX对于写操作无能为力"); } /* * 接收注释声明事件的通知。 * 参数意义如下: * name - 注释名称。 * publicId - 注释的公共标识符,如果未提供,则为 null。 * systemId - 注释的系统标识符,如果未提供,则为 null。 */ @Override public void notationDecl(String name, String publicId, String systemId) throws SAXException { super.notationDecl(name, publicId, systemId); } /* * 接收用来查找 SAX 文档事件起源的对象。 * 参数意义如下: * locator : 可以返回任何 SAX 文档事件位置的对象 */ @Override public void setDocumentLocator(Locator locator) { super.setDocumentLocator(locator); } //一般将正式解析前的一些初始化工作放到这里面,收尾工作放在endDocument中 @Override public void startDocument() throws SAXException { System.err.println("开始解析文档"); } //接受文档结尾的通知 @Override public void endDocument() throws SAXException { System.err.println("解析结束"); } /* * 接收元素开始的通知。 * XML解析器遇到XML里面的tag时就会调用这个函数。经常在这个函数内是通过localName俩进行判断而操作一些数据。 * 参数意义如下: * uri :元素的命名空间 * localName :元素的本地名称(不带前缀) * qName :元素的限定名(带前缀) * attributes :元素的属性集合 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //System.out.print(" "+"Element: " + qName + ", attr: "); //print(attributes); int i=attributes.getLength(); for(int j=0;j<i;j++) { //String strName=attributes.getLocalName(j); //String strValue=attributes.getValue(j); //System.out.println(strName+":"+strValue); } if(qName=="operation") { strOperationtag=attributes.getValue(0); } if(qName=="input") { strMessageName=attributes.getValue(0); strOptName=attributes.getValue(1); strBaseValue=attributes.getValue(2); } switch(strOptName) { case("大于"): if(Double.parseDouble(value)>Double.parseDouble(strBaseValue)) { signtag=1; } break; case("小于"): if(Double.parseDouble(value)<Double.parseDouble(strBaseValue)) { signtag=2; } break; case("等于"): signtag=3;break; case("大于等于"): signtag=4;break; default: signtag=0;break; } if(signtag!=0) { if(qName=="output") { System.out.println(attributes.getValue(1)); signtag=0; strBaseValue=""; strMessageName=""; strOptName=""; } } } /* * @接受元素尾部通知(non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) * @uri 元素命名空间 * @localName 元素本地名称 * @qName 元素限定名 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { //super.endElement(uri, localName, qName); if(qName=="operation") { strOperationtag=""; } } /*接受字符数据的通知 * 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue) * 碰到节点开始和结束之间的字符 * 回调方法。解析器执行完startElement()后,解析完节点的内容后就会执行这个方法,并且参数ch[]就是节点的内容。 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //super.characters(ch, start, length); this.str.append(ch,start,length); } private void print(Attributes attrs) { if (attrs == null) return; System.err.print("["); for (int i = 0; i < attrs.getLength(); i++) { System.err.print(attrs.getQName(i) + " = " + attrs.getValue(i)); if (i != attrs.getLength() - 1) { System.err.print(", "); } } System.err.println("]"); } }
参考资料:
http://yangjunfeng.iteye.com/blog/401377
http://www.blogjava.net/DLevin/archive/2012/11/18/391545.html
http://www.ibm.com/developerworks/cn/xml/x-saxapi/