zoukankan      html  css  js  c++  java
  • 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("
    "+"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/

  • 相关阅读:
    布局(layout)文件图形界面不能显示:An error has occurred. See error log for more details. java.lang.NullPointe
    Mac下无法推出硬盘
    Excel导入导出数据库(MVC)
    json导入数据库
    XML导入数据库
    Excel表格导入数据库
    Lambda高级查询
    Linq高级查询
    多线程
    反射
  • 原文地址:https://www.cnblogs.com/villa/p/3909434.html
Copyright © 2011-2022 走看看