Download - Fórum

Guia do Usuário Conteúdo

  1. Conhecimento Prévio Necessário
  2. Clássico "Hello World" com SAX
  3. Clássico "Hello World" com JColtrane
  4. Anotações Básicas de Condição
  5. Opcões de Filtragem de Elementos
  6. Outras Formas de Filtragem
  7. Construindo Suas Próprias Condições de Filtragem
  8. Como Receber Parâmetros do JColtrane
  9. Extendendo o Processamento XML.

Ajude a manter o projeto

Opcões de Filtragem de Elementos

Para facilitar o processamento, JColtrane apresenta algumas opções para filtrar elementos do XML de acordo com o desejo do usuário. Para ilustrar essas opções, usaremos o código XML abaixo:

<?xml version="1.0" encoding="UTF-8"?>

<beanDescriptor>

      <line>

            <property  mandatory="true" page="4" language="pt" />           

            <property2  mandatory="false"  language="pt" />

      </line>

</beanDescriptor>

Seguindo os passos apresentados na seção Clássico "Hello World" com JColtrane,

vamos construir uma classe básica para executar algumas ações quando estiver iniciando a finalizando um elemento:

public class StartAndEndElemetAction {

      @StartElement

      public void executeInStartElement(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in start element\n");

      }

 

      @EndElement

      public void executeInEndElement(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element\n");

      }

}

Agora, codificaremos uma classe passando a anterior como parâmetro para o JColtraneXMLHandler:

public class FilteringTest {

      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\\example2\\Example2.xml");

            if(parser!=null){

                  InputSource input=new InputSource(file.getAbsolutePath());

                  try {

                        parser.parse(input,new JColtraneXMLHandler(new StartAndEndElemetAction()));

                  } catch (SAXException e) {

                        e.printStackTrace();

                  } catch (IOException e) {

                        e.printStackTrace();

                  }

            }

      }

}

Rodando a classe anterior, o sistema imprime:

/beanDescriptor/
Executing something in start element

/beanDescriptor/line/
Executing something in start element

/beanDescriptor/line/property/
Executing something in start element

/beanDescriptor/line/property/
Executing something in end element

/beanDescriptor/line/property2/
Executing something in start element

/beanDescriptor/line/property2/
Executing something in end element

/beanDescriptor/line/
Executing something in end element

/beanDescriptor/
Executing something in end element

Como você pode ver, o JColtrane executou o que queríamos: invocou os métodos quando estava iniciando ou finalizando qualquer elemento. Mas vamos dizer que você quisesse executar o primeiro método somente quando um elemento contendo a tag "line" iniciasse e quisesse, ainda, que o segundo método executasse somente quando qualquer elemento contendo a tag com sufixo "property" estivesse terminando . Para fazer isso, faremos as alterações marcadas no código de StartAndEndElementAction:

public class StartAndEndElemetAction {

      @StartElement(tag="line")

      public void executeInStartElement(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in start element\n");

      }

 

      @EndElement(tag="property.*")

      public void executeInEndElement(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element\n");

      }

}

Executando FilteringTest novamente, o sistema imprime:

/beanDescriptor/line/
Executing something in start element

/beanDescriptor/line/property/
Executing something in end element

/beanDescriptor/line/property2/
Executing something in end elemen

Como você pode ver, JColtrane fêz exatamente o que queríamos. No primeiro método colocamos a propriedade tag com valor "line". No segundo, colocamos o valor "property.*". Esse último valor é uma expressão regular. Assim, você pode usar expressões regulares (regex do JAVA) para filtrar elementos.

Além da propriedade tag , você pode usar as propriedades uri e localName também. Essas propriedades recebem, respectivamente, uri e nome local do elemento.

Vamos considerar agora que você deseje executar um método quando um elemento está finalizando e contenha um atributo de nome "mandatory". Você deseja executar outro método com uma condição similar, mas quer uma condição adicional, quer que o elemento contenha um atributo de nome "page" com valor "4" e que contenha também um atributo contenha o valor "pt". Para fazer isso, escrevemos a seguinte classe:

public class EndElemetAction {

      @EndElement(attributes={@ContainAttribute(name="mandatory")})

      public void executeInEndElement1(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element with attribute mandatory\n");

      }

     

      @EndElement(attributes={@ContainAttribute(name="mandatory"),@ContainAttribute(name="page",value="4")})

      public void executeInEndElement2(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element with some attribute with name mandatory and another with name page and value 4\n");

      }

     

      @EndElement(attributes={@ContainAttribute(value="pt")})

      public void executeInEndElement3(@CurrentBranch String currentBrunch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element with some attribute with value pt\n");

      }

}

Rodando um teste, passando a classe acima, como fizemos nos demais exemplos, o sistema imprime:

/beanDescriptor/line/property/
Executing something in end element with attribute mandatory

/beanDescriptor/line/property/
Executing something in end element with some attribute with name mandatory and another with name page and value 4

/beanDescriptor/line/property/
Executing something in end element with some attribute with value pt

/beanDescriptor/line/property2/
Executing something in end element with attribute mandatory

/beanDescriptor/line/property2/
Executing something in end element with some attribute with value pt

Como você pode notar, cada método foi executado quando o elemento estava finalizando e quando o mesmo satisfazia as condições. Se você quiser colocar mais condições, você só precisaria colocar mais anotações do tipo ContainAttribute com duas propriedade desejadas. Ambos atributos do ContainAttribute, name e value, aceitam expressões regurares.

Se você reparar no resultado apresentado, existem métodos sendo executados devido ao mesmo elemento estar finalizando, já que as condição de todos foram satisfeitas, como, por exemplo, o elemento /beanDescriptor/line/property/. Nós não informamos o JColtrane sobre a ordem que desejamos fazer a execução, se mais de um método for executar. Suponhamos que você deseje executar os métodos nessa ordem: primeiro executeInEndElement3, depois executeInEndElement1 e depois executeInEndElement2. Você quer executar nessa ordem quando eles executarem no mesmo "tempo", ou seja, em nosso caso quando /beanDescriptor/line/property/ ou /beanDescriptor/line/property2/ estão finalizando. Façamos algumas mudanças em nossa classe para informar o JColtrane a ordem que desejamos:

public class EndElemetAction {

      @EndElement(priority=2,attributes={@ContainAttribute(name="mandatory")})

      public void executeInEndElement1(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element with attribute mandatory\n");

      }

     

      @EndElement(attributes={@ContainAttribute(name="mandatory"),@ContainAttribute(name="page",value="4")})

      public void executeInEndElement2(@CurrentBranch String currentBranch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element with some attribute with name mandatory and another with name page and value 4\n");

      }

     

      @EndElement(priority=3,attributes={@ContainAttribute(value="pt")})

      public void executeInEndElement3(@CurrentBranch String currentBrunch){

            System.out.println(currentBranch);

            System.out.println("Executing something in end element with some attribute with value pt\n");

      }

}

Executando o teste com as mudanças, temos:

/beanDescriptor/line/property/
Executing something in end element with some attribute with value pt

/beanDescriptor/line/property/
Executing something in end element with attribute mandatory

/beanDescriptor/line/property/
Executing something in end element with some attribute with name mandatory and another with name page and value 4

/beanDescriptor/line/property2/
Executing something in end element with some attribute with value pt

/beanDescriptor/line/property2/
Executing something in end element with attribute mandatory

Como você pode ver, temos o resultado desejado usando a propriedade priority. Métodos anotados com maior priority serão executatos antes daqueles com menor priority.

JColtrane atribui valor de priority 0 (zero) por default. Essa é a razão pela qual não atribuimos ao método executeInEndElement2 um valor para priority e mesmo assim ele executou sempre depois dos demais métodos.

Resumimos todas as opções abaixo:

Opção Argumentos Significado
tag regex elemento deve ter tag que é aceita pela expressão regular
uri regex elemento deve ter uri que é aceita pela expressão regular
localName regex elemento deve ter nome local que é aceito pela expressão regular
priority int métodos com prioridades maiores serão executos antes, caso mais de um método seja executado no mesmo "momento"
ContainAtribute ( regex name , regex value ) o elemento deve conter um atributo reconhecido pela expressão regular de name e value

Agora que você sabe as opções básicas, veja Outras Formas de Filtragem.