SAX解析XML总结

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("\n"+"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("\n"+"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/

posted on 2014-08-13 10:37  建业v  阅读(515)  评论(0编辑  收藏  举报

导航