Clássico "Hello World" com SAX
Nesse tutorial usaremos vários exemplos. Todos podem ser encontrados com o donwload do framework, na pasta examples.
Começaremos com o clássico exemplo "Hello World". Para ilustrar a análise XML, será usado o seguinte documento XML:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" >
body of the property
</property >
</line>
</beanDescriptor>
Na abordagem do SAX, você teria que extender DefaultHandler, codificando uma classe semelhante a que se segue:
public class SAXHandler extends DefaultHandler {
private StringBuilder currentBranch=new StringBuilder("/");
private StringBuilder body= new StringBuilder();
public void startDocument(){
System.out.println("Starting Document: Hello World!!!\n");
}
public void endDocument(){
System.out.println("End Document: Bye bye World!!!\n");
}
public void startElement(String uri,String localName,String tag,Attributes atributos)throws SAXException{
currentBranch.append(tag+"/");
System.out.println(currentBranch.toString());
//user action
System.out.println("Executing some action in start element\n");
body.delete(0,body.length());
}
public void endElement(String uri,String localName,String tag)throws SAXException{
if(!body.toString().equals("\n")&&body.length()!=2)
System.out.println(body.toString().trim());
System.out.println(currentBranch);
body.delete(0, body.length());
//user action
System.out.println("Executing some action in end element\n");
currentBranch.delete(currentBranch.length()-tag.length()-1, currentBrunch.length());
}
public void characters(char[] ch, int start, int lenght)throws SAXException{
body.append(ch,start,lenght);
}
}
Da classe anterior, podemos fazer algumas observações:
- Você deve sobreescrever métodos definidos na classe DefaultHandler.
- Nos métodos startElement e endElement você precisa receber alguns parâmetros, mesmo que você não os precise usar.
- Se você precisar manter alguma informação sobre o XML, deverá implementar sua maneira de manter esses dados (en nosso caso, foram usados objetos StringBuilder para manter o galho atual e o corpo do documento XML).
Depois de implementar tudo isso, você poderia criar uma classe para imprimir o resultado da análise, comprovando que a mesma está correta:
public class SAXHandlerTest {
public static void main(String[] args) {
SAXParser parser=null;
try {
parser= SAXParserFactory.newInstance().newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
File file=new File("examples\\example1\\Example1.xml");
if(parser!=null){
InputSource input=new InputSource(file.getAbsolutePath());
try {
parser.parse(input,new SAXHandler());
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Executando a classe anterior, o sistema imprime o seguinte resultado:
Starting Document: Hello World!!!
/beanDescriptor/
Executing some action in start element
/beanDescriptor/line/
Executing some action in start element
/beanDescriptor/line/property/
Executing some action in start element
body of the property
/beanDescriptor/line/property/
Executing some action in end element
/beanDescriptor/line/
Executing some action in end element
/beanDescriptor/
Executing some action in end element
End Document: Bye bye World!!!
É claro que você poderia encapsular suas ações em suas próprias classes customizadas, fazendo uma injeção de dependência na classe. Mas mesmo fazendo isso, você precisaria receber alguns parâmetros e fazer o código para tratar dados da forma que desejar. E, se você precisar de informações do passado, como o galho corrente (current branch) em nosso exemplo, você deverá implementar isso.
Vamos realizar a mesma análise usando o JColtrane na próxima seção Clássico "Hello World" com JColtrane.