日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)其它知識(shí) → 使用XML 就應(yīng)該簡單點(diǎn)

      使用XML 就應(yīng)該簡單點(diǎn)

      相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:本站整理時(shí)間:2011/3/13 21:07:44字體大。A-A+

      作者:佚名點(diǎn)擊:66次評(píng)論:0次標(biāo)簽: XML

      • 類型:下載工具大。828KB語言:中文 評(píng)分:7.5
      • 標(biāo)簽:
      立即下載

      對(duì)于現(xiàn)在越來越輕量級(jí),越來越講究速度和接近用戶的應(yīng)用來說,xml確實(shí)有點(diǎn)復(fù)雜了。解析起來不僅耗內(nèi)存,而且很復(fù)雜。這就好像花了幾千塊錢買了個(gè)MS Office,但是80%的feature都用不著,還白白的耗著CPU和內(nèi)存。

      個(gè)人覺得,設(shè)置文件用XML其實(shí)挺好,因?yàn)樵O(shè)置文件一般并不太大,而且要求可讀性強(qiáng),還有很多亂七八糟的需求,可以利用XML的力量。昨天搞chrome的設(shè)置,發(fā)現(xiàn)chrome的設(shè)置文件也是使用的json,讀起來也是輕松愉快。

      前陣子做了個(gè)程序,需要解析豆瓣API調(diào)用返回的XML。真想說一句。。。豆瓣你別用XML了。。。至少,提供個(gè)json版的API調(diào)用吧。

      (以上謹(jǐn)代表個(gè)人觀點(diǎn))

      ===================正文=================

      解析豆瓣返回的xml,實(shí)在是不想用DOM這個(gè)重量級(jí)的玩意。DOM這個(gè)玩意,說它強(qiáng)大好還是說它官僚好呢。我傾向于使用SAXP解析。但是現(xiàn)在面臨的一個(gè)問題是,我需要根據(jù)xml節(jié)點(diǎn)的名字和屬性值(一個(gè)或者多個(gè))來決定當(dāng)前的值是不是我想要的。這就麻煩一點(diǎn)點(diǎn)。第一反應(yīng)是考慮xpath。后來覺得不如自己做一個(gè)得了,權(quán)當(dāng)是按需定制一個(gè)輕量級(jí)的xpath。

      首先定義XMLSearchUnit類,這個(gè)類的實(shí)例用來描述一個(gè)需要在XML中搜索的值,值可以是xml節(jié)點(diǎn)的值,或者是節(jié)點(diǎn)的屬性。

      package com.deepnighttwo.resourceresolver.douban.resolver.utils;

      import java.util.HashMap;
      import java.util.Map;

      import org.xml.sax.Attributes;

      /**
      *
      * Represent a search task. Target could be value of a node or attribute of the
      * node.
      *
      *
      @author mzang
      */
      publicclass XMLSearchUnit {

      // attribute values to be matched during search
      private Map<String, String> attributeMatchValidation =new HashMap<String, String>();

      // if target is an attribute, then set this member to be the attribute name.
      // if it is null or empty, then means the target is node value.
      private String expectedAttr;

      // xml path, format is: /node_name/node_name/...
      private String xmlPath;

      public XMLSearchUnit(String xmlPath) {
      this.xmlPath = xmlPath;
      }

      /**
      * if current node meets the search conditions or not. Meets means the path
      * is correct and the attribute value is matched.
      *
      *
      @param path
      *
      @param attributes
      *
      @return
      */
      publicboolean match(String path, Attributes attributes) {
      if (xmlPath.equals(path) ==false) {
      returnfalse;
      }

      for (String key : attributeMatchValidation.keySet()) {
      String exp
      = attributeMatchValidation.get(key);
      String compare
      = attributes.getValue(key);
      if (exp.equalsIgnoreCase(compare) ==false) {
      returnfalse;
      }
      }
      returntrue;
      }

      public Map<String, String> getAttributeMatchValidation() {
      return attributeMatchValidation;
      }

      publicvoid addAttributeValidation(String key, String value) {
      attributeMatchValidation.put(key, value);
      }

      public String getXmlPath() {
      return xmlPath;
      }

      publicvoid setAttributeMatchValidation(
      Map
      <String, String> attributeMatchValidation) {
      this.attributeMatchValidation = attributeMatchValidation;
      }

      public String getExpectedAttr() {
      return expectedAttr;
      }

      /**
      * if target is node value, then set expectedAttr to null. if target is an
      * attribute value, set it to be the attribute name.
      *
      *
      @param expectedAttr
      */
      publicvoid setExpectedAttr(String expectedAttr) {
      this.expectedAttr = expectedAttr;
      }

      /**
      * hash code can be cached if all properties are not be be changed.
      */
      @Override
      publicint hashCode() {
      finalint prime =31;
      int result =1;
      result
      = prime
      * result
      + ((attributeMatchValidation ==null) ?0
      : attributeMatchValidation.hashCode());
      result
      = prime * result
      + ((expectedAttr ==null) ?0 : expectedAttr.hashCode());
      result
      = prime * result + ((xmlPath ==null) ?0 : xmlPath.hashCode());
      return result;
      }

      @Override
      publicboolean equals(Object obj) {
      if (this== obj)
      returntrue;
      if (obj ==null)
      returnfalse;
      if (getClass() != obj.getClass())
      returnfalse;
      XMLSearchUnit other
      = (XMLSearchUnit) obj;
      if (attributeMatchValidation ==null) {
      if (other.attributeMatchValidation !=null)
      returnfalse;
      }
      elseif (!attributeMatchValidation
      .equals(other.attributeMatchValidation))
      returnfalse;
      if (expectedAttr ==null) {
      if (other.expectedAttr !=null)
      returnfalse;
      }
      elseif (!expectedAttr.equals(other.expectedAttr))
      returnfalse;
      if (xmlPath ==null) {
      if (other.xmlPath !=null)
      returnfalse;
      }
      elseif (!xmlPath.equals(other.xmlPath))
      returnfalse;
      returntrue;
      }

      }

      這個(gè)類比較簡單。就是用一個(gè)hashmap保待匹配的attribut鍵值對(duì),用一個(gè)字符串表示期待的attribute name,用一個(gè)字符串表示期待的node path。

      然后就是如何在SAXP里用到這個(gè)類的實(shí)例去搜索了。

      package com.deepnighttwo.resourceresolver.douban.resolver.utils;

      import java.io.InputStream;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;

      import javax.xml.parsers.SAXParser;
      import javax.xml.parsers.SAXParserFactory;

      import org.xml.sax.Attributes;
      import org.xml.sax.InputSource;
      import org.xml.sax.SAXException;
      import org.xml.sax.XMLReader;
      import org.xml.sax.helpers.DefaultHandler;

      /**
      *
      * SAXP parser working with XMLSearchUnit.
      *
      *
      @author mzang
      */

      publicclass DoubanSearchParser extends DefaultHandler {

      // create and initial search units
      publicstaticfinal XMLSearchUnit DETAILS_LINK_API_PATH =new XMLSearchUnit(
      "/feed/entry/id");

      publicstaticfinal XMLSearchUnit DETAILS_CONTENT_PATH =new XMLSearchUnit(
      "/entry/summary");

      publicstaticfinal XMLSearchUnit DETAILS_TITLE_PATH =new XMLSearchUnit(
      "/entry/title");

      publicstaticfinal XMLSearchUnit DETAILS_CHINESE_NAME_PATH =new XMLSearchUnit(
      "/entry/db:attribute");

      publicstaticfinal XMLSearchUnit DETAILS_RATINGE_PATH =new XMLSearchUnit(
      "/entry/gd:rating");

      publicstaticfinal XMLSearchUnit DETAILS_RATINGE_RATER_COUNT_PATH =new XMLSearchUnit(
      "/entry/gd:rating");

      publicstaticfinal XMLSearchUnit DETAILS_LINK_URL_PATH =new XMLSearchUnit(
      "/feed/entry/link");

      static {
      DETAILS_LINK_URL_PATH.addAttributeValidation(
      "rel", "alternate");
      DETAILS_LINK_URL_PATH.setExpectedAttr(
      "href");

      DETAILS_CHINESE_NAME_PATH.addAttributeValidation(
      "lang", "zh_CN");
      DETAILS_CHINESE_NAME_PATH.addAttributeValidation(
      "name", "aka");

      DETAILS_RATINGE_PATH.setExpectedAttr(
      "average");

      DETAILS_RATINGE_RATER_COUNT_PATH.setExpectedAttr(
      "numRaters");

      }

      // a map to store the XMLSearchUnit and value
      private Map<XMLSearchUnit, String> results =new HashMap<XMLSearchUnit, String>();

      // a counter of search unit. if it is 0, then all search unit finds a match
      // value and the result of the XML will be skipped.
      privateint count =0;

      private StringBuilder path =new StringBuilder();

      privatestaticfinal String pathSeparater ="/";

      private XMLSearchUnit[] searchUnits;

      List
      <XMLSearchUnit> foundItems =new ArrayList<XMLSearchUnit>();

      /**
      * constructor, accept XML input stream, 0 or more search unit instances.
      *
      *
      @param input
      *
      @param expectedPath
      *
      @return
      */
      public Map<XMLSearchUnit, String> parseResults(InputStream input,
      XMLSearchUnit... expectedPath) {
      for (XMLSearchUnit search : expectedPath) {
      results.put(search,
      null);
      }

      searchUnits
      = expectedPath;

      count
      = expectedPath.length;

      XMLReader xmlReader
      =null;
      try {
      SAXParserFactory spfactory
      = SAXParserFactory.newInstance();
      spfactory.setValidating(
      false);
      SAXParser saxParser
      = spfactory.newSAXParser();
      xmlReader
      = saxParser.getXMLReader();
      xmlReader.setContentHandler(
      this);
      xmlReader.parse(
      new InputSource(input));
      }
      catch (Exception e) {
      System.err.println(e);
      System.exit(
      1);
      }
      return results;
      }

      privatevoid addToPath(String addPath) {
      path.append(pathSeparater).append(addPath.toLowerCase());
      }

      privatevoid popPath() {
      int index = path.lastIndexOf(pathSeparater);
      // String removedPath = path.substring(index);
      path.delete(index, path.length());
      }

      @Override
      publicvoid startElement(String uri, String localName, String qName,
      Attributes attributes)
      throws SAXException {
      foundItems.clear();
      if (count ==0) {
      return;
      }

      // update path
      addToPath(qName);

      List
      <XMLSearchUnit> foundAttrItems =null;

      // check if current node matches search units. if it is a node value
      // search, then store it in a member variable named foundItems because
      // the value of the node is known only when reaches the end of the
      // node.but for attribute search, it value is known here. So then are
      // put in a local variable list named foundAttrItems.
      for (XMLSearchUnit unit : searchUnits) {
      if (unit.match(path.toString(), attributes) ==true) {

      if (unit.getExpectedAttr() ==null) {
      foundItems.add(unit);
      }
      else {
      if (foundAttrItems ==null) {
      foundAttrItems
      =new ArrayList<XMLSearchUnit>();
      }
      foundAttrItems.add(unit);
      }
      }
      }
      // if no attribute match, return.
      if (foundAttrItems ==null) {
      return;
      }

      // fill search unit value using attribute value. update count.
      for (XMLSearchUnit attrUnit : foundAttrItems) {
      String attrValue
      = attributes.getValue(attrUnit.getExpectedAttr());
      if (results.get(attrUnit) ==null) {
      count
      --;
      }
      results.put(attrUnit, attrValue);
      count
      --;
      }
      }

      /**
      * if current node matches, the the node value is useful, store it.
      */
      @Override
      publicvoid characters(char[] ch, int start, int length)
      throws SAXException {
      if (count ==0) {
      return;
      }
      if (foundItems.size() ==0) {
      return;
      }

      for (XMLSearchUnit unit : foundItems) {
      String content
      =new String(ch, start, length);
      if (results.get(unit) ==null) {
      count
      --;
      }
      results.put(unit, content);
      }
      }

      @Override
      publicvoid endElement(String uri, String localName, String qName)
      throws SAXException {
      foundItems.clear();
      if (count ==0) {
      return;
      }
      popPath();
      }
      }

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無聊無聊

        熱門評(píng)論

        最新評(píng)論

        發(fā)表評(píng)論 查看所有評(píng)論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)