How does this ANTLR 3 convert to ANTLR4? [duplicate] - parsing

In ANTLR 3 you could just do the following:
andExpression
: (andnotExpression -> andnotExpression)
(AND? a=andnotExpression -> ^(AndNode $andExpression $a))*
;
Any idea how to do it in the new version?

As mentioned by Sam (280Z28), ANTLR 4 does not have rewrite operators.
When generating the parser, ANTLR 4 creates some listener classes that you can use to listen for "enter" and "exit" events of all parser rules.
Also, ANTLR 4 supports "direct left recursive rules", so your expression rules can be defined in a single rule as demonstrated below:
grammar Expr;
parse
: expression EOF
;
expression
: '(' expression ')'
| IDENTIFIER
| NOT expression
| expression AND? expression
| expression OR expression
;
LPAREN : '(';
RPAREN : ')';
NOT : 'NOT';
AND : 'AND';
OR : 'OR';
IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]*;
SPACE : [ \t\r\n]+ -> skip;
When parsing the input "a b OR NOT c AND d", the following parse tree will be created:
(image created using ANTLRWorks2, thank you Sam! Very impressive IDE, I love it!)
Generate the parser and listener classes:
java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Expr.g4
and the following class is generated that will let you help "walk" the tree:
public class ExprBaseListener implements ExprListener {
#Override public void enterExpression(ExprParser.ExpressionContext ctx) { }
#Override public void exitExpression(ExprParser.ExpressionContext ctx) { }
#Override public void enterParse(ExprParser.ParseContext ctx) { }
#Override public void exitParse(ExprParser.ParseContext ctx) { }
#Override public void enterEveryRule(ParserRuleContext<Token> ctx) { }
#Override public void exitEveryRule(ParserRuleContext<Token> ctx) { }
#Override public void visitTerminal(TerminalNode<Token> node) { }
#Override public void visitErrorNode(ErrorNode<Token> node) { }
}
Now you'll need to inspect the ExprParser.ExpressionContext to see which of the alternatives in expression is matched, which is where "tree-labels" come in handy. Change the expression rule as follows:
expression
: '(' expression ')' # EXPR
| IDENTIFIER # ID_EXPR
| 'NOT' expression # NOT_EXPR
| expression 'AND'? expression # AND_EXPR
| expression 'OR' expression # OR_EXPR
;
and regenerate the parser and listeners, and you'll see that ExprBaseListener now looks like this:
public class ExprBaseListener implements ExprListener {
#Override public void enterAND_EXPR(ExprParser.AND_EXPRContext ctx) { }
#Override public void exitAND_EXPR(ExprParser.AND_EXPRContext ctx) { }
#Override public void enterOR_EXPR(ExprParser.OR_EXPRContext ctx) { }
#Override public void exitOR_EXPR(ExprParser.OR_EXPRContext ctx) { }
#Override public void enterEXPR(ExprParser.EXPRContext ctx) { }
#Override public void exitEXPR(ExprParser.EXPRContext ctx) { }
#Override public void enterNOT_EXPR(ExprParser.NOT_EXPRContext ctx) { }
#Override public void exitNOT_EXPR(ExprParser.NOT_EXPRContext ctx) { }
#Override public void enterID_EXPR(ExprParser.ID_EXPRContext ctx) { }
#Override public void exitID_EXPR(ExprParser.ID_EXPRContext ctx) { }
#Override public void enterParse(ExprParser.ParseContext ctx) { }
#Override public void exitParse(ExprParser.ParseContext ctx) { }
#Override public void enterEveryRule(ParserRuleContext ctx) { }
#Override public void exitEveryRule(ParserRuleContext ctx) { }
#Override public void visitTerminal(TerminalNode node) { }
#Override public void visitErrorNode(ErrorNode node) { }
}
I.e., for each label in expression a separate enter- and exit-method is created.
Now, let's say you're only interested in enter-events of the AND expression. You could create a custom class that extends this ExprBaseListener and override enterAND_EXPR:
public class ExprWalker extends ExprBaseListener {
#Override
public void enterAND_EXPR(ExprParser.AND_EXPRContext ctx) {
java.util.List<ExprParser.ExpressionContext> e = ctx.expression();
System.out.println("AND -> " + e.get(0).getText() + ", " + e.get(1).getText());
}
}
To test this all, create a small driver class:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Main {
public static void main(String[] args) throws Exception {
String input = "a b OR NOT c AND d";
ExprLexer lexer = new ExprLexer(new ANTLRInputStream(input));
ExprParser parser = new ExprParser(new CommonTokenStream(lexer));
ParseTree tree = parser.parse();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new ExprWalker(), tree);
}
}
and run it:
java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Expr.g4
javac -cp antlr-4.0-complete.jar *.java
java -cp .:antlr-4.0-complete.jar Main
after which you'll see the following being printed to your console:
AND -> a, bORNOTcANDd
AND -> NOTc, d

ANTLR 4 does not have a rewrite operator or an output=AST option like ANTLR 3. Trees produced by ANTLR 4 parsers are parse trees, the shape of which is implicitly defined by the grammar rules.

Related

extension function using saxon s9api

I am trying to add an extension function, but is failing with :
Caused by: net.sf.saxon.trans.XPathException: Unknown system function follow()
at net.sf.saxon.expr.parser.XPathParser.grumble(XPathParser.java:282)
I see (in debug) that function registered with the integrated library. I was expecting saxon to look for the function in the integrated library but it is searching in system functions and throwing error. What is causing this function to be represented as a system function.
I am using the following :
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>9.7.0-14</version>
</dependency>
Thank you
my code is
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.lib.ExtensionFunctionCall;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathExecutable;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.value.SequenceType;
public class FollowTest {
public static void main(String[] args) throws Exception {
new FollowTest().test();
}
private void test () throws Exception {
Processor proc = new Processor(false);
proc.registerExtensionFunction(new Follow());
XPathCompiler xx = proc.newXPathCompiler();
XPathExecutable x = xx.compile("follow(/a/b/c)/type='xyz'");
}
public class Follow extends ExtensionFunctionDefinition {
#Override
public StructuredQName getFunctionQName() {
return new StructuredQName("", "http://example.com/saxon-extension", "follow");
}
#Override
public int getMinimumNumberOfArguments() {
return 1;
}
#Override
public int getMaximumNumberOfArguments() {
return 1;
}
#Override
public SequenceType[] getArgumentTypes() {
return new net.sf.saxon.value.SequenceType[] {SequenceType.SINGLE_STRING,};
}
#Override
public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
return SequenceType.NODE_SEQUENCE;
}
#Override
public boolean trustResultType() {
return true;
}
#Override
public boolean dependsOnFocus() {
return false;
}
#Override
public boolean hasSideEffects() {
return false;
}
#Override
public ExtensionFunctionCall makeCallExpression() {
return null;
}
private class followCall extends ExtensionFunctionCall {
#Override
public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
return null;
}
}
}
}
In the XPath expression you have written
follow(/a/b/c)
A function name with no namespace prefix is assumed to be in the default namespace for functions, which by default is the system function namespace http://www.w3.org/2005/xpath-functions. You need to use a prefix that's bound to the URI appearing in the extension function definition, namely http://example.com/saxon-extension

Why TextWatcher is not working in custom Edittext in android?

I am working on custom edittext but i am little stuck in one thing, i found TextWatcher is not working in custom edittext.
public class InputValidation extends EditText {
public InputValidation(Context context) {
super(context);
}
public InputValidation(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InputValidation(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void addTextChangedListener(android.text.TextWatcher watcher) {
super.addTextChangedListener(new TextWatcherDelegator());
}
public class TextWatcherDelegator implements android.text.TextWatcher {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
android.util.Log.d("TextWatcher", " beforeTextChanged :: " + charSequence.toString());
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(android.text.Editable editable) {
android.util.Log.d("TextWatcher", " afterTextChanged :: " + editable.toString());
}
}
}
XML layout
<com.example.inputvalidation.InputValidation
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:hint="Fullname"
android:singleLine="true"
android:textSize="20sp"/>
Above this code it's not at all calling TextWatcher states, please kindly go through my code and suggest me some solution.
Remove this, it's useless:
#Override
public void addTextChangedListener(android.text.TextWatcher watcher) {
super.addTextChangedListener(new TextWatcherDelegator());
}
Then, add/remove the TextWatcher properly, for example in onAttachedToWindow/onDetachedFromWindow methods:
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
addTextChangedListener(textWatcher);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
removeTextChangedListener(textWatcher);
}
Also, textWatcher should be an object, so it can be instanced from the TextWatcherDelegator class:
TextWatcherDelegator textWatcher = new TextWatcherDelegator();
Or directly from TextWatcher (which is better, if there's no other usages for TextWatcherDelegator):
public TextWatcher textWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
android.util.Log.d("TextWatcher", " beforeTextChanged :: " + charSequence.toString());
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(android.text.Editable editable) {
android.util.Log.d("TextWatcher", " afterTextChanged :: " + editable.toString());
}
}

org.springframework.beans.factory.BeanCreationException using cdi

I am trying to implement authentication and authorization using Spring Security Framework, but I am having a hard time, Im stuck in this exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clienteBO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected br.com.logtec.dao.GenericCrudDAO br.com.logtec.business.GenericCrudBO.dao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'crudDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected javax.persistence.EntityManager br.com.logtec.dao.GenericCrudDAO.entityManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.persistence.EntityManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.inject.Inject(), #br.com.logtec.factory.DataFactory()}
Those are my related classes:
#Named("clienteBO")
public class ClienteBO extends PersonificacaoBO<Cliente>{
private static final long serialVersionUID = 119528316663693560L;
public ClienteBO() {
super();
}
#Override
public Feedback salvar(Cliente instancia) {
instancia.getPessoa().setCliente(true);
//TODO PEGAR EMPRESA DO USUARIO LOGADO
// if(instancia.getEmpresa() == null)
// throw new RuntimeException("O cliente deve obrigatoriamente possuir uma empresa");
return super.salvar(instancia);
}
#Override
public Feedback salvar(Cliente instancia, CrudDAO<Cliente> dao) {
instancia.getPessoa().setCliente(true);
return super.salvar(instancia, dao);
}
#Override
protected Exemplo criarExemplo(Cliente pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return super.criarExemplo(pesquisa);
}
#Override
public Feedback salvar(Collection<Cliente> instancias) {
for (Cliente cliente : instancias) {
cliente.getPessoa().setCliente(true);
}
return super.salvar(instancias);
}
#Override
public Feedback salvar(Collection<Cliente> instancias, CrudDAO<Cliente> dao) {
for (Cliente cliente : instancias) {
cliente.getPessoa().setCliente(true);
}
return super.salvar(instancias, dao);
}
}
public abstract class PersonificacaoBO<T extends Personificacao> extends GenericCrudBO<T>{
private static final long serialVersionUID = 5475960092794378740L;
#Override
protected Exemplo criarExemplo(T pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Exemplo exemplo = super.criarExemplo(pesquisa);
exemplo.excludeField("pessoa.cliente");
exemplo.excludeField("pessoa.funcionario");
exemplo.excludeField("pessoa.fornecedor");
exemplo.excludeField("pessoa.usuario");
exemplo.excludeField("pessoa.contador");
return exemplo;
}
}
#Named("crudBO")
public class GenericCrudBO<E extends EntidadeBase> implements CrudBO<E>{
private static final long serialVersionUID = 1L;
private static final String DEFAULT_ERROR_MESSAGE = "Um erro inesperado ocorreu, contate o administrador do sistema.";
private static final String DEFAULT_SUCESS_MESSAGE = "Operação realizada com sucesso!";
#Inject
#Named("crudDAO")
protected GenericCrudDAO<E> dao;
public GenericCrudBO() {
super();
}
public GenericCrudBO(GenericCrudDAO<E> dao) {
super();
this.dao = dao;
}
public Feedback salvar(E instancia, CrudDAO<E> dao) {
Feedback feedback;
try {
dao.atualizar(instancia);
feedback = new Feedback(TipoFeedback.SUCESSO, EtapaFeedback.CADASTRO, DEFAULT_SUCESS_MESSAGE);
} catch (RuntimeException e) {
feedback = new Feedback(TipoFeedback.ERRO, EtapaFeedback.CADASTRO, DEFAULT_ERROR_MESSAGE);
throw e;
}
return feedback;
}
public Feedback salvar(Collection<E> instancias, CrudDAO<E> dao) {
try {
dao.cadastrar(instancias);
return new Feedback(TipoFeedback.SUCESSO, EtapaFeedback.CADASTRO, "Operação realizada com sucesso");
} catch (Exception e) {
return new Feedback(TipoFeedback.ERRO, EtapaFeedback.CADASTRO, "Erro ao salvar, contate o administrador");
}
}
#Override
public Feedback salvar(Collection<E> instancias) {
return salvar(instancias, dao);
}
public Feedback salvar(E instancia) {
return salvar(instancia, dao);
}
#Override
public Feedback deletar(E entidade) {
Feedback feedback;
try {
dao.deletar(entidade);
feedback = new Feedback(TipoFeedback.SUCESSO, EtapaFeedback.CADASTRO, DEFAULT_SUCESS_MESSAGE);
} catch (RuntimeException e) {
feedback = new Feedback(TipoFeedback.ERRO, EtapaFeedback.DELECAO, DEFAULT_ERROR_MESSAGE);
}
return feedback;
}
public E pesquisarPorId(Class<E> clazz, Long id) {
return dao.pesquisarPorId(clazz, id);
}
public E pesquisarPorId(E instancia) {
return dao.pesquisarPorId(instancia);
}
public List<E> pesquisar(Class<E> clazz) {
return dao.pesquisarTodos(clazz);
}
/**
* Pesquisa para entidades simples sem composição
*/
#Override
public List<E> pesquisar(E pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Exemplo exemplo = criarExemplo(pesquisa);
return dao.pesquisar(exemplo);
}
protected Exemplo criarExemplo(E pesquisa) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Exemplo exemplo = new Exemplo(pesquisa);
exemplo.excludeField("serialVersionUID");
exemplo.setMatchingMode(MatchingMode.ANYWHERE);
exemplo.excludeZeroes();
return exemplo;
}
#Override
public int total(E pesquisa) {
return this.dao.total(pesquisa);
}
public List<E> listarLazy(E pesquisa, int startingAt, int maxPerPage, String sortField, String sortOrder) {
inicializarCamposPesquisa(pesquisa);
return this.dao.listarLazy(pesquisa, startingAt, maxPerPage, sortField, sortOrder);
}
protected void inicializarCamposPesquisa(E pesquisa) {
//método que deverá ser implementado pelas classes filhas que quiserem filtrar os resultados no lazyList
}
public String getListIds(List<EntidadeBase> entidades) {
StringBuilder builder = new StringBuilder('(');
EntidadeBase e = null;
for (int i = 0; i < entidades.size(); i++) {
e = entidades.get(i);
builder.append(e.getId());
if(i < entidades.size()-1) {
builder.append(',');
}
}
builder.append(')');
return builder.toString();
}
#SuppressWarnings("unchecked")
protected Class<E> getClassType() {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
return (Class<E>) parameterizedType.getActualTypeArguments()[0];
}
}
#Named("crudDAO")
public class GenericCrudDAO<E extends EntidadeBase> implements CrudDAO<E>{
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(CrudDAO.class);
#Inject
#DataFactory
protected EntityManager entityManager;
public GenericCrudDAO() {
super();
}
public GenericCrudDAO(EntityManager entityManager) {
super();
this.entityManager = entityManager;
}
#Override
public void cadastrar(E instancia) {
entityManager.getTransaction().begin();
entityManager.persist(instancia);
entityManager.getTransaction().commit();
}
public void cadastrar(Collection<E> instancias) {
try {
entityManager.getTransaction().begin();
for(E e : instancias) {
entityManager.merge(e);
}
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
throw e;
}
}
#Override
public void atualizar(E instancia) {
entityManager.getTransaction().begin();
entityManager.merge(instancia);
entityManager.getTransaction().commit();
}
#Override
public void deletar(E instancia) {
entityManager.getTransaction().begin();
entityManager.remove(entityManager.merge(instancia));
entityManager.getTransaction().commit();
}
public E pesquisarPorId(Class<E> clazz, Long id) {
return (E) entityManager.find(clazz, id);
}
#SuppressWarnings("unchecked")
public E pesquisarPorId(E instancia) {
Class<E> clazz = (Class<E>) instancia.getClass();
return (E) entityManager.find(clazz, instancia.getId());
}
#SuppressWarnings("unchecked")
public List<E> pesquisarTodos(Class<E> clazz) {
List<E> lista = new ArrayList<E>();
lista = entityManager.createQuery(" FROM " + clazz.getName()).getResultList();
return lista;
}
#Override
public List<E> pesquisar(Exemplo exemplo) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return QBE.using(entityManager).getList(exemplo);
}
#Override
public E pesquisarUnico(Exemplo exemplo) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return QBE.using(entityManager).getSingle(exemplo);
}
#Override
#SuppressWarnings("unchecked")
public List<E> pesquisar(String queryString) {
return entityManager.createQuery(queryString).getResultList();
}
#SuppressWarnings("unchecked")
#Override
public List<E> pesquisar(String queryString, Map<String, Object> param) {
String key = null;
Query query = entityManager.createQuery(queryString);
for(Map.Entry<String, Object> entry : param.entrySet()) {
key = entry.getKey().trim();
key = key.startsWith(":") ? key.substring(1) : key;
query.setParameter(key, entry.getValue());
}
return query.getResultList();
}
public int total(E pesquisa) {
Long count = 0L;
try {;
Query q = entityManager.createQuery("SELECT count(*) FROM "
+ pesquisa.getClass().getName());
count = (Long) q.getSingleResult();
} catch (Exception e) {
LOGGER.error("Erro ao buscar total listagem lazy", e);
}
return count.intValue();
}
public void rollback() {
entityManager.getTransaction().rollback();
}
#SuppressWarnings("unchecked")
protected Class<E> getClassType() {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
return (Class<E>) parameterizedType.getActualTypeArguments()[0];
}
#SuppressWarnings("unchecked")
public List<E> listarLazy(E pesquisa, int startingAt, int maxPerPage,
String sortField, String sortOrder) {
List<E> lista = new ArrayList<E>();
try {
Query q = entityManager.createQuery("FROM "
+ pesquisa.getClass().getName());
q.setFirstResult(startingAt);
q.setMaxResults(maxPerPage);
lista = q.getResultList();
} catch (Exception e) {
LOGGER.error("Erro ao buscar listagem Lazy", e);
}
return lista;
}
}
I'm a begginer on Spring Security, being so, any help is welcome, thanks
If I get this right, you want to use Spring Security for security and CDI for dependency injection.
In that case, you need to make sure that Spring and CDI don't try to manage the same beans. Even when you don't use Spring Core directly, you now have both Spring and CDI on your classpath. When Spring discovers javax.inject.Inject on its classpath, it will treat #Inject as synonymous to #Autowired and try to inject Spring beans into the annotated injection target.
That's why you get the exception - it's Spring and not CDI complaining about a missing bean.

How to get parent of a custom component?

I have a custom container component, that I want to use like this:
<p:a>A
<p:a>B</p:a>
</p:a>
That should generate this markup:
<div>A
<div>B</div>
</div>
Code for the component is below.
public class TagA extends TagHandler {
Logger logger = Logger.getLogger(getClass().getName());
public TagA(TagConfig config) {
super(config);
}
public void apply(FaceletContext ctx, UIComponent parent)
throws IOException {
UIComponentBase c = new UIComponentBase() {
public void encodeBegin(FacesContext ctx) throws IOException {
//getParent() always returns UIViewRot
logger.info("Parent is: " + getParent().getClass().getName());
ResponseWriter w = ctx.getResponseWriter();
w.write("<div>");
super.encodeBegin(ctx);
}
public void encodeEnd(FacesContext ctx) throws IOException {
ResponseWriter w = ctx.getResponseWriter();
w.write("</div>");
super.encodeEnd(ctx);
}
// abstract method in base, must override
public String getFamily() {
return "com.mobiarch.nf";
}
};
parent.getChildren().add(c);
nextHandler.apply(ctx, parent);
}
}
Unfortunately, this is rendering the following markup:
<div></div>A
<div></div>B
For others in a similar situation, just develop the component and not the tag.
#FacesComponent("my.ComponentA")
public class ComponentA extends UIComponentBase {
Logger logger = Logger.getLogger(getClass().getName());
public String getFamily() {
return "my.custom.component";
}
public void encodeBegin(FacesContext ctx) throws IOException {
super.encodeBegin(ctx);
logger.info("Component parent is: " + getParent().getClass().getName());
ResponseWriter w = ctx.getResponseWriter();
w.write("<div>");
}
public void encodeEnd(FacesContext ctx) throws IOException {
super.encodeEnd(ctx);
ResponseWriter w = ctx.getResponseWriter();
w.write("</div>");
}
}
Register it in your ??.taglib.xml
<tag>
<tag-name>a</tag-name>
<component>
<component-type>my.ComponentA</component-type>
</component>
</tag>

running Sax parser

Am new to using SAX parser .Can anyone tell me how to run it .and what all are required to run it (jdk )..Can i have a sax parser that can parse both android xml and a normal xml
SAX parsers are implemented by creating a ContentHandler object which implements certain callback functions that correspond to events that happen while parsing an XML document. For example, the startDocument method is called when the parser begins parsing the document, and startElement is called when it discovers a new tag; similarly, endElement, endDocument, and error are called when the parser finds the end of a tag or document, or when an invalid sequence is discovered.
This example shows how to use a SAX parser. The key is that the MyHandler class extends the DefaultHandler class (which implements the ContentHandler interface) and overrides the empty implementations of each callback method.
Think of it this way: the Java SAXParser class knows how to parse XML documents but when it discovers things of interest it relies on some handler class to know what to do with them. The DefaultHandler class is a helper implementation which you can extend to pay attention to the interesting things.
You could use a ContentHandler directly (see below) instead of extending the DefaultHandler if you want. I believe this level of SAX parsing is available on the Android platform.
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
public class Demo {
public static void main(String[] args) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(new MyContentHandler());
xr.parse("input.xml");
}
private static class MyContentHandler implements ContentHandler {
public void setDocumentLocator(Locator locator) {
}
public void startDocument() throws SAXException {
}
public void endDocument() throws SAXException {
}
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
}
public void endPrefixMapping(String prefix) throws SAXException {
}
public void startElement(String uri, String localName, String qName,
System.out.println("START " + qName);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("END " + qName);
}
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
}
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
}
public void processingInstruction(String target, String data)
throws SAXException {
}
public void skippedEntity(String name) throws SAXException {
}
}
}

Resources