这篇“XMLSearchUnit类怎么定义”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“XMLSearchUnit类怎么定义”文章吧。
首先定义XMLSearchUnit类,这个类的实例用来描述一个需要在XML中搜索的值,值可以是xml节点的值,或者是节点的属性。
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(); } }
以上就是关于“XMLSearchUnit类怎么定义”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。