package blade.migrate.core; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * @author Andy Wu */ public class XMLFileChecker { public XMLFileChecker(File file) { _file = file; SAXParserFactory factory = SAXParserFactory.newInstance(); try { _parser = factory.newSAXParser(); _parser.getXMLReader().setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); } catch (ParserConfigurationException | SAXException e) { new IllegalArgumentException(e); } } public List<SearchResult> findTag(String tagName, String value) { // start parsing the given file and generates results SearchExecutor searcher = new SearchExecutor(tagName, value); try { _parser.parse(_file, searcher); } catch (SAXException | IOException e) { e.printStackTrace(); } return searcher.getResults(); } private File _file; private SAXParser _parser; private class SearchExecutor extends DefaultHandler { public SearchExecutor(String tagName, String value) { _tagName = tagName; _value = value; _results = new ArrayList<>(); } @Override public void characters(char[] ch, int start, int length) throws SAXException { String content = new String(ch, start, length); if (inState && _value != null && _value.equals(content)) { _results.add( new SearchResult( _file, 0, 0, locator.getLineNumber(), locator.getLineNumber(), true)); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // reset the state when goes to end of each element inState = false; } public List<SearchResult> getResults() { return _results; } @Override public void setDocumentLocator(final Locator locator) { this.locator = locator; } @Override public void startDocument() throws SAXException { _results.clear(); } @Override public void startElement( String uri, String localName, String qName, Attributes attributes) throws SAXException { if (_tagName.equals(qName) && _value != null) { inState = true; } else if (_tagName.equals(qName) && _value == null) { _results.add( new SearchResult( _file, 0, 0, locator.getLineNumber(), locator.getLineNumber(), true)); } } private List<SearchResult> _results = null; private String _tagName; private String _value; // is in the target Tag private boolean inState = false; private Locator locator; } }