Aprendendo Apache XMLBEANS

17 respostas
G

No mundo J2EE, o poderoso xml está cada vez mais presente, e sendo representado e utilizado de diversas formas e tecnologias,

  • podendo ser através de web-services,
  • como camada middleware representando entidade comum para comunicação de sistemas;
  • ou mesmo como dados em ambientes de integração;

e é nesse mundo que entra os XMLBEANS.

A idéia XMLBEAN foi desenvolvida pela BEA Systems , sendo utilizada como recurso na maioria de seus produtos; em Setembro de 2003 a tecnologia foi doado para a Apache para ela dar continuidade ao projeto.

Aprendendo XMLBEANS

O XMLBean é uma maneira de representar e manipular dados e documentos em XML através do Java.

O foco principal de um XMLBEAN é um XML Schema ( arquivo XSD ). No arquivo XSD é definido como os dados são representados indicando os seus atributos e também sua tipagem.

A idéia aqui é a mesma de quando você escreve o codigo em um arquivo TLD para criar uma nova TAG JSP.

No TLD você descreve como deve funcionar, "quais são as regras a seguir" ;; e no JSP voce simplesmente utiliza a tag.

É através dos Schemas (XSD) é que os dados serão ?instanciados? e serão representados em arquivos XML.

Pensemos da seguinte maneira:: "O XSD é a classe e o xml é o objeto da classe"

Imagine sua classe Vo chamado Pessoa com os atributos nome e sobrenome:

Mãos a obra, vamos programar:

public class Pessoa{

private String nome;
private String sobrenome;

public String getNome(){
peturn nome;
}

public String getSobrenome(){
return sobrenome;
}

public void setNome(String paramNome){
nome = paramNome;
}

public void setSobrenome(String paramSobrenome){
sobrenome = paramSobrenome;
}
}

Agora vamos criar uma instância da classe Pessoa:

Pessoa pessoa = new Pessoa();
Pessoa.setNome("Fulano");
Pessoa.setSobrenome("de Tal");

Quando criamos um objeto de uma determinada classe, especificamente falando de VOs, estamos criando uma estrutura e um comportamento predefinido pela classe, ou seja, através dos códigos acima voce tem o objeto pessoa que está guardando a informação ?Fulano? e ?de Tal? em seus atributos Nome e Sobrenome respectivamente e seguindo exatamente as normas regidas pela sua classe.

Agora faremos a mesma coisa utilizando XMLBEANS.

Definindo sua "Classe"

Quando voce escreve um Vo… voce começa escrevendo a classe com seus atributos e métodos get e set para cada atributo…

É isso que faremos agora…

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://openuri.org/easypo" 
xmlns:po="http://openuri.org/easypo"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xs:element name="Pessoa">
<xs:complexType>
<xs:sequence>
<xs:element name="nome" type="xs:string"/>
<xs:element name="sobrenome" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Credo!!! meu Deus!! O que é isso aí em cima??? Isso aí em cima é um arquivo XSD ( Schema ) nele percebemos a definição do nome da classe ?Pessoa? como um elemento principal e dentro do corpo é definido propriedades ?também elemento? que representa os atributos da nossa classe Pessoa para só depois fechar o elemento principal “Pessoa”.

Não se preocupe com a sintaxe e definição das tags, pois raramente vai criar um xsd na mão a partir do zero. Existem ferramentas para geração do arquivo, o foco aqui é entender a idéia do que é um xsd.

Instanciando um objeto da classe Pessoa

Agora faremos uma instância da nossa classe e atribuiremos informação aos atributos do nosso objeto .

<po:Pessoa xmlns:po="http://openuri.org/easypo">
<po:Pessoa>
<po:nome>Fulano</po:nome>
<po:sobrenome>de Tal</po:sobrenome>
</po:Pessoa>
</po:Pessoa>

Vemos no xml acima que ele segue as normas regidas pelo xsd (“classe”) e que a propriedade ?po:nome? tem o conteúdo ?Fulano? e a propriedade ?po:sobrenome? tem o conteúdo ?de Tal? e ambos estão cobertos pelo emento principal chamado Pessoa.

Acessando atributos do objeto

Da mesma maneira que invoco get e set do meu objeto Vo em Java eu também posso acessar e alterar meu XMLBEAN.

Carregando xml…

PessoaDocument pesDoc = PessoaDocument.Factory.parse(new File("Pessoa.xml"));
Pessoa pes = pesDoc.getPessoa();

Acima temos um objeto principal representando o documento e só através dele é que pegamos o objeto Vo.
… pegando dados

pes.getNome();
pes.getSobrenome();

… alterando dados

pes.setNome( ?ciclano?);

Ei??? é igual ao VO Java??? é fácil assim??? cadê o SAX e o DOM??? Sim meu pequeno gafanhoto é tão fácil quanto.
No Java eu posso dar um new e criar um novo objeto a qualquer momento e em xmlBean como eu faço isso???

PessoaDocument pesDoc = PessoaDocument.Factory.newInstance();
Pessoa novaPessoa = PessoaDocument.addNewPessoa();

Pronto… agora é só aplicar get e set sobre o objeto novaPessoa… igual voce faria em um objeto Vo comum.

Vantagens e desvantagens

Ei??? Qual é a vantagem do xmlbean sobre o meu Vo java comum???

Bom, acredito que o arquivo xml é muito mais portável que o objeto Vo java type… pois pode ser acessado a qualquer momento e por qualquer aplicação aonde quer que ela esteja; em outro contexto; em outro servidor; em outra rede; em outro continente… aff exagerei!!! rsrrs e também seguindo as regras definidas por voce no seu Schema ( XSD)

Uhnnn ahh legal!!! Intão vou trocar todos os meus VOs por xmlbeans???

O fato de carregar e descarregar arquivo xml e ter SAX e DOM para manipulação xml por traz do framework implica em performance em aplicações, portanto a utilização de xmlbeans é encargo do desenvolvedor viabilizando custo/beneficio e visando também o tamanho de sua aplicação.

Acredito que as reais vantagens no emprego de XMLBEANS é quando voce gostaria que um determinado Vo fique disponível para acesso externo independente de tecnologia e local físico/lógico.

Se você realmente se interessou pela tecnologia, por favor não se atenha a esse texto tabajara, prossiga seus estudos através dos links abaixo!!!

Referências

Pagina Apache XMLBeans - Documentação - Tutoriais - Downloads - Exemplos
http://xmlbeans.apache.org

Eclipse plug-in - geração de arquivos xsd / xml / java ( value objects )
http://sourceforge.net/projects/xmlbeansplug

Eclipse Plug-in geracao de arquivos xsd a partir de java code
http://www.java-x.us

Artigo dev2dev BEA ? XMLBEANS - Getting Started
http://e-docs.bea.com/workshop/docs81/doc/en/workshop/guide/xmlbeans/conGettingStartedwithXMLBeans.html



Gabriel Ishigami Solana
SCJP - Sun Certificied Java Programmer
SCWCD - Sun Certificied Web Components Developer
Linux user #440457
http://counter.li.org

17 Respostas

D

Com que finalidade você está usando os beans gerados com o XML Beans?

D

Opa! Comecei a trabalhar com a plataforma da BEA…

O pessoal usa bastante como parametro de métodos de WebServices…

Ah! Uma outra coisa bacana é fazer transformação de um XML para outro XML com layouts diferentes…

Abaços!

D

Inútil para web services se você usa algo como Apache Axis ou outro engine.

D

Como disse sou novo com a plataforma… não podemos julgar só pelas minhas palavras… vamos na fonte…

http://www.bea.com/

Só um detalhe… o WebLogic… usa o Apache Axis como engine…

:lol:

Até+…

P

http://fragmental.com.br/wiki/index.php?title=Evitando_VOs_e_BOs

G

Sim, é possível…criar mais de um objeto pessoa

No exemplo eu criei como simple type…
mas voce pode criar mais uma ramificação… e repetir o pessoa… na hora de transformar em objeto java… vai vir como array

Exemplificando::

Veja que voce tem um element persons: que no corpo da tag dele tem uma sequence de elements person

&lt?xml version=“1.0” encoding=“ISO-8859-1”?&gt
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault=“qualified”>

<xs:element name=“persons”>
<xs:complexType>
<xs:sequence>
<xs:element name=“person” maxOccurs=“unbounded”>
<xs:complexType>
<xs:sequence>
<xs:element name=“full_name” type=“xs:string”/>
<xs:element name=“child_name” type="xs:string"
minOccurs=“0” maxOccurs=“5”/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>

o xml desse xsd ficaria algo parecido com isso::

&lt?xml version=“1.0” encoding=“ISO-8859-1”?&gt<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=“family.xsd”><person>
<full_name>Hege Refsnes</full_name>
<child_name>Cecilie</child_name>
</person><person>
<full_name>Tove Refsnes</full_name>
<child_name>Hege</child_name>
<child_name>Stale</child_name>
<child_name>Jim</child_name>
<child_name>Borge</child_name>
</person><person>
<full_name>Stale Refsnes</full_name>
</person></persons>

G

Complementando…

Para gerar classes Java a partir do XSD

1- Ajustar variaveis de ambiente

export XMLBEANS_HOME=
export PATH=$PATH:$XMLBEANS_HOME/bin
export CLASSPATH=$XMLBEANS_HOME/lib/xbean.jar:$CLASSPATH

2 - Executar comando scomp para gerar classes

Ex::
scomp -out tutorials\gettingstarted\lib\easypo.jar schemas\easypo\easypo.xsd

primeiro parametro é o local e o nome do jar com as classes
segundo parametro é aonde esta o xsd

A

como eu faço para cria r o PessoaDocument??

G

Duas maneiras de se obter o objeto pessoa document.

um eh criando um novo xml… e outro ehh carregando um xml jah existente.

Cria um novo xml.

PessoaDocument pesDoc = PessoaDocument.Factory.newInstance(); Pessoa novaPessoa = PessoaDocument.addNewPessoa();

carrega o xml existente.

R

Olá, galera,

Estou tentando usar o xmlBeans para trabalhar com a NFe, mas estou obtendo um problema com o objeto retornado pelo pelo método parse. Todos os objetos (tags) com exceção do objeto raiz, estão vindo null. Os getters estão obedecendo a estrutura definida pelo XSD, porém estão todos null.

o arquivo xsd que estou usando é o leiauteNFe_v2.00.xsd

se alguém pudar ajudar, agradeço :smiley:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		File file = new File("C:\\Files\\NFEXML.xml");
		try{	
						
		    TNfeProc doc = TNfeProc.Factory.parse(file);
		    System.out.println(doc.getProtNFe());
		    System.out.println(doc.getNFe());		    		    
		    System.out.println(doc.getVersao());
		    
		    /* output:
		     * null
		     * null
		     * null
		     */
		}
		catch(XmlException e){
			e.printStackTrace();
		}
		catch(Exception e){
			e.printStackTrace();
		}

	}
G

Ola Rafael,

Experimente re-gerar as classes java através do xsd, pode ser que voce tenha alterado a estrutura
e não tenha feito isso.

Escrevi esse tutorial a bastante tempo e hoje existe implementação da própria Sun - chama-se JAXB.

É bem simples, somente algumas nomenclaturas mudam. funciona da mesma forma, após escrever o
xsd é necessário rodar um comando para gerar as classes java.

Exemplos…
http://www.oracle.com/technetwork/articles/javase/index-140168.html

A

Será que seu arquivo.xml que vc esta fazendo o parse esta sem definições de namespace ou com definições incorretas?

R

Gabiso, estou tentando usar o JAXB:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		try{
			File file = new File("C:\\Files\\NFEXML.xml");
			JAXBContext context = JAXBContext.newInstance("br.inf.portalfiscal.nfe");
			Unmarshaller un = context.createUnmarshaller();						
			TNfeProc nfe = (TNfeProc) un.unmarshal(file);
			
		}
		catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}	
	}

mas na linha 7 estou obtendo o seguinte erro:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.portalfiscal.inf.br/nfe", local:"nfeProc"). Expected elements are (none)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:631)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:236)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:231)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1038)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:467)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:448)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:626)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3095)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:922)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
	at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
	at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:142)
	at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:151)
	at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:169)
	at jaxb_test.C1.main(C1.java:26)

ei gerei todas as classes a partir de todos os esquemas XSD contidos na pasta PL_006g (a mais recente) do portal da NFe (http://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=/fwLvLUSmU8=)

não estou sabendo como corrigir esse erro. Se alguem puder dar alguma dica, ajudaria muito :smiley:

R

Criei um tutorial bem simples no meu blog ensinando como começar com xmlbeans.

Segue o link: http://robsonp.com/01/2011/xml-com-xmlbeans/

Valeu

S

Amigos, pensando em um CTe e usando XMLBEANS, vamos supor que no campo e o valor vá como null, quando eu gero o xml as seguintes tags são marcadas no resultado, onde diz que nas tags do exemplo o valor é null.

Gostaria de saber se existe uma maneira de remover estas tags caso elas sejam null, alguma parametrização no XMLBEAN que me permite configura-lo para mostrar ou não!

O ideal seria estas tags não vir no xml remove-las!

<pag> 
      <cnpj xsi:nil="true"/> 
</pag> 

<receb> 
      <cnpj xsi:nil="true"/> 
</receb>

Obrigado!

R

Shakall acredito que se você tá gerando os Beans a partir do Schema não tem como você deixar de gerar estas tags. Você terá que fazer a verificação pra ver se é null.

S

Entendi, puts fods vai dar uma trabalheira!

Criado 3 de maio de 2006
Ultima resposta 26 de nov. de 2012
Respostas 17
Participantes 9