溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

XMLSearchUnit類怎么定義

發(fā)布時間:2022-01-15 10:01:41 來源:億速云 閱讀:120 作者:iii 欄目:web開發(fā)

這篇“XMLSearchUnit類怎么定義”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“XMLSearchUnit類怎么定義”文章吧。

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

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   */  public class 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       */      public boolean match(String path, Attributes attributes) {          if (xmlPath.equals(path) == false) {              return false;          }           for (String key : attributeMatchValidation.keySet()) {              String exp = attributeMatchValidation.get(key);              String compare = attributes.getValue(key);              if (exp.equalsIgnoreCase(compare) == false) {                  return false;              }          }          return true;      }       public Map<String, String> getAttributeMatchValidation() {          return attributeMatchValidation;      }       public void addAttributeValidation(String key, String value) {          attributeMatchValidation.put(key, value);      }       public String getXmlPath() {          return xmlPath;      }       public void 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       */      public void setExpectedAttr(String expectedAttr) {          this.expectedAttr = expectedAttr;      }       /**       * hash code can be cached if all properties are not be be changed.       */      @Override      public int hashCode() {          final int 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      public boolean equals(Object obj) {          if (this == obj)              return true;          if (obj == null)              return false;          if (getClass() != obj.getClass())              return false;          XMLSearchUnit other = (XMLSearchUnit) obj;          if (attributeMatchValidation == null) {              if (other.attributeMatchValidation != null)                  return false;          } else if (!attributeMatchValidation                  .equals(other.attributeMatchValidation))              return false;          if (expectedAttr == null) {              if (other.expectedAttr != null)                  return false;          } else if (!expectedAttr.equals(other.expectedAttr))              return false;          if (xmlPath == null) {              if (other.xmlPath != null)                  return false;          } else if (!xmlPath.equals(other.xmlPath))              return false;          return true;      }   }

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

然后就是如何在SAXP里用到這個類的實例去搜索了。

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   */   public class DoubanSearchParser extends DefaultHandler {       // create and initial search units      public static final XMLSearchUnit DETAILS_LINK_API_PATH = new XMLSearchUnit(              "/feed/entry/id");       public static final XMLSearchUnit DETAILS_CONTENT_PATH = new XMLSearchUnit(              "/entry/summary");       public static final XMLSearchUnit DETAILS_TITLE_PATH = new XMLSearchUnit(              "/entry/title");       public static final XMLSearchUnit DETAILS_CHINESE_NAME_PATH = new XMLSearchUnit(              "/entry/db:attribute");       public static final XMLSearchUnit DETAILS_RATINGE_PATH = new XMLSearchUnit(              "/entry/gd:rating");       public static final XMLSearchUnit DETAILS_RATINGE_RATER_COUNT_PATH = new XMLSearchUnit(              "/entry/gd:rating");       public static final 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.      private int count = 0;       private StringBuilder path = new StringBuilder();       private static final 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;      }       private void addToPath(String addPath) {          path.append(pathSeparater).append(addPath.toLowerCase());      }       private void popPath() {          int index = path.lastIndexOf(pathSeparater);          // String removedPath = path.substring(index);          path.delete(index, path.length());      }       @Override      public void 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      public void 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      public void endElement(String uri, String localName, String qName)              throws SAXException {          foundItems.clear();          if (count == 0) {              return;          }          popPath();      }  }

以上就是關(guān)于“XMLSearchUnit類怎么定義”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI