Lendo XML + JDOM

Pessoal, to precisando de ajuda

quero ler um xml e acontece que meu XML pode ter varias tags repetidas.

Por exemplo

<mensagem>
<nome>Fulano</nome>
<contato>11111</contato>
</mensagem>
<mensagem>
<nome>Beltrano</nome>
<contato>22222</contato>
</mensagem>

E como eu to usando JDom, meu código ta assim:

System.out.println(elemento..getChildText( "nome"));
System.out.println(elemento..getChildText( "contato"));

como tem dois contatos, se eu colocar no “for” ou “while”, ele fica percorrendo somente o primeiro.
Como resolver isso?

vc precisa ter um ROOT … um marca raiz, que não se repita, algo assim

<app> <mensagem> <nome>Fulano</nome> <contato>11111</contato> </mensagem> <mensagem> <nome>Beltrano</nome> <contato>22222</contato> </mensagem> <mensagem> <nome>Abacwssda</nome> <contato>12321312</contato> </mensagem> <mensagem> <nome>adsadaDAds</nome> <contato>12313123</contato> </mensagem> <mensagem> <nome>Adsadsa</nome> <contato>435435</contato> </mensagem> </app>

ai da pra recuperar assim

public static void main(String ... args) throws Throwable { URL url = new URL("file:///C:/xml.xml"); SAXReader reader = new SAXReader(); final Document document = reader.read(url); Iterable<Element> iterable = new Iterable<Element>() { @Override @SuppressWarnings("unchecked") public Iterator<Element> iterator() { return document.getRootElement().elementIterator(); } }; for (Element e : iterable) { System.out.println("nome = "+ e.elementText("nome")); System.out.println("contato = "+ e.elementText("nome")); } }

só uma observação, não precisa criar um new Iterable … mais é que não gosto de iterator ^^ uhaauhhua … prefiro colocar direto no for

Ou usa o JColtrane e não se preocupa mais com isso…

eu não sei exatamente c tem que ter o root… sei que meu navegador não le XML sem o raiz… e só sei usar o dom4j quando tem raiz ^^

Fiz um exemplo aqui:

[code]public class LeitorDeContatoNomeEContato {
@BeforeElement(tag=“mensagem”, elementDeep = 1)
@EndElement(tag=“nome”)
private void imprimirNome(@Body String nome){
System.out.println(nome);
}

@BeforeElement(tag="mensagem", elementDeep = 1)
@EndElement(tag="contato")
private void imprimirContato(@Body String contato){
	System.out.println(contato);
}

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("src\xml\msg.xml"); 
    if(parser!=null){ 
          InputSource input=new InputSource(file.getAbsolutePath()); 
          try { 
                parser.parse(input,new JColtraneXMLHandler(new LeitorDeContatoNomeEContato())); 
          } catch (SAXException e) { 
                e.printStackTrace(); 
          } catch (IOException e) { 
                e.printStackTrace(); 
          } 
    } 

}

}
[/code]

quando fiz o parsing do seu arquivo, deu uma exceção:

Fulano
11111
org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.

Ou seja, ele imprimiu os dois primeiro e deu pau quando viu que não tem root. Aí eu coloquei um root no seu documento e imprimiu tudo certinho:

Fulano
11111
Beltrano
22222

Ou seja, o Lavieri tava certo. Eu tb não sabia que era necessário um root. Vivendo e aprendendo…

pois é renzonuccitelli … ^^ … o mesmo que falei la pro dom4j … que faltava o ROOT … ai coloquei APP de root só como exemplo

Mas a duvida ainda persiste…

e se o arquivo não tiver diretamente ligado ao elemento raiz?

por exemplo…

<texto>
      <mensagemGeral>
             <mensagem>   
                    <nome>Fulano</nome>   
                   <contato>11111</contato>   
            </mensagem>   
            <mensagem>   
                   <nome>Beltrano</nome>   
                   <contato>22222</contato>   
           </mensagem>  
     </mensagemGeral>
</texto>

dessa forma eu tambem pego o valor iterando?

Sim, da mesma forma vc vai ter que iterar. Pelo que vi, o root é requerido mesmo, o que já era de se esperar pela Exceção lançada.

[quote=javaCBA]Mas a duvida ainda persiste…

e se o arquivo não tiver diretamente ligado ao elemento raiz?

por exemplo…

<texto>
      <mensagemGeral>
             <mensagem>   
                    <nome>Fulano</nome>   
                   <contato>11111</contato>   
            </mensagem>   
            <mensagem>   
                   <nome>Beltrano</nome>   
                   <contato>22222</contato>   
           </mensagem>  
     </mensagemGeral>
</texto>

dessa forma eu tambem pego o valor iterando?[/quote]

Pega sim, basta primeiro vc pegar o elemento mensagemGeral, depois é so fazer pegar o iterator dos elementos dele, e usar em um for ou onde achar conviniente…

Conforme o XML que vc enviou, uma das formas de solicionar é assim:

public static void main(String ... args) throws Throwable { URL url = new URL("file:///C:/xml.xml"); SAXReader reader = new SAXReader(); final Document document = reader.read(url); for (Element e : getIterable(document,"mensagemGeral")) { System.out.println("nome = "+ e.elementText("nome")); System.out.println("contato = "+ e.elementText("nome")); } } private static Iterable<Element> getIterable(final Document document, final String element) { return new Iterable<Element>() { @Override @SuppressWarnings("unchecked") public Iterator<Element> iterator() { return document.getRootElement().element(element).elementIterator(); } }; }

Note que ele busca o elemnto “mensagemGeral”, e faz um iterator a partir dele… e coloca dentro de um Iterable, pra vc usar facilmente em um for

veja que quebrei em 2 métodos… criei um método apenas para montar o Iterable…

os parametros do método getIterable, são:

  • “document” que é o documento ao qual deve-se buscar os elementos
  • “element” que é uma String com o nome do sub elemento que se deseja criar o Iterable, que no seu caso é “mensagemGeral”

EDIT: apenas para facilitar, os imports usados nesse exemplo são

[code]import java.net.URL;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;[/code]

ola, desculpa se estou postando na pagina errada.
Mais estou com uma duvida e sou novato em java. Encontrei um codigo para ler um xml de retorno de um outro aplicativo.
Quando faço a leitura do xml ele me retorna resultado null
segue o codigo:

[code]
File f = new File(“C:/mural.xml”);

                    //Criamos uma classe SAXBuilder que vai processar o XML4

org.jdom.input.SAXBuilder sb = new org.jdom.input.SAXBuilder();

//Este documento agora possui toda a estrutura do arquivo.
org.jdom.Document d = null;
try {
d = sb.build(f);
} catch (JDOMException ex) {
Logger.getLogger(Assistec.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Assistec.class.getName()).log(Level.SEVERE, null, ex);
}

//Recuperamos o elemento root
org.jdom.Element mural = d.getRootElement();

//Recuperamos os elementos filhos (children)
List elements = mural.getChildren();
Iterator i = elements.iterator();

//Iteramos com os elementos filhos, e filhos do dos filhos
while (i.hasNext()) {
Element element = (Element) i.next();
System.out.println(“Códido:”+ element.getChildText(“cStat”));
}[/code]

segue o xml

<?xml version="1.0" encoding="utf-8"?>
<retAltConfUniNFe>
<cStat>1</cStat>
<xmotivo>Configuracao do UniNFe alterada com sucesso</xmotivo>
</retAltConfUniNFe>