Como percorrer esse XML de maneira eficaz?[RESOLVIDO]

20 respostas
P

Tenho o seguinte xml:

<VDNs_XX>
    
    <Skill Numero="55" Nome="Real">    
        <VDN Numero="83630" Status="Ativo" Label="xxxx"/>
        <VDN Numero="83631" Status="Desativado" Label="yyyy"/>
        <VDN Numero="83632" Status="Ativo" Label="aaaa"/>
        <VDN Numero="83633" Status="Ativo" Label="ccccc"/>    
    </Skill>
    
</VDNs_XX>

Como pegar os valores de cada propriedade dessas tags usando o Dom:

Eu usava assim, mas para pegar algo em:
aaaa

Como adaptar esse código?:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(getClass().getResource("VDN.xml").toString());
NodeList nl = doc.getElementsByTagName(tag);
String chave = nl.item(indice).getFirstChild().getNodeValue();

20 Respostas

A

Já tentou usar o xpath???

Acho mais intuitivo…

public String RetornaConteudoXML (String caminhoNodo) throws Exception
	{

		return (String) xpath.evaluate(caminhoNodo, doc, XPathConstants.STRING);
		
	}

Aí, so seu caso, seria utilizando a sintaxe… por exemplo…

você passaria VDNs_XX\Skill\VDN[2]@Status para o método acima e ele te retornaria o o valor status do segundo VDN… no seu caso, a String “Destativado”…

A sintaxe do Xpath está em http://www.w3schools.com/xpath/default.asp

Tomara que tenha te ajudado um pouco…

P

Cara, não consegui usar esse seu método, preciso adicionar algum jar?, ele não tá completo?

A

Opa… realmente tá completo não bicho…

Deixa ver os jar aqui…

Segue os imports…

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.xpath.XPath;

import javax.xml.xpath.XPathConstants;

import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

Além disso… os atributos

private Document doc;

private DocumentBuilder parser;

private XPath xpath;

E o método pra carregar o DOM e atribuir ao XPATH… achei que esse tu já
tinha feito:

public LeitorXml (String caminhoArquivoXML)  throws Exception
	{		
		
		parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		doc = parser.parse(new File(caminhoArquivoXML));
		xpath = XPathFactory.newInstance().newXPath();
	}
P

Fiz assim mas não está retornando nada:

public static void main(String[] args) {
   ManipulaXML teste = new ManipulaXML();
   try {
      System.out.println(teste.retornaConteudoXML("/VDN.xml"));
   } catch (Exception e) {
      e.printStackTrace();
   }
}
	
private Document doc; 
private DocumentBuilder parser; 
private XPath xpath; 
	
public String retornaConteudoXML (String caminhoArquivoXML) throws Exception{
   parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
   doc = parser.parse(new File(caminhoArquivoXML));
   xpath = XPathFactory.newInstance().newXPath();
   return (String) xpath.evaluate(caminhoArquivoXML, doc, PathConstants.STRING);
}
A

Seguinte, acho que o que aconteceu foi um mau entendido…

A palavra é a mesma, caminho, mas um é o caminho físico do arquivo (C:\Arquivos de programa\xmlFiles\teste.xml, por exemplo) e o outro é o caminho Xpath ( VDNs_XX\Skill\VDN[2]@Status, exemplo do seu caso);

Pro construtor da classe LeitorXml (que te passei o código lá) você passa o caminho do arquivo xml que deseja ler.

Pro método retornaConteudoXML você passa o caminho xpath desejado.

Então… nada de teste.retornarConteudoXML("/VDN.xml"))…

Ficaria algo assim:

LeitorXml leitor = new LeitorXml(VDN.xml);


Syso(leitor.retornaConteudoXML( VDNs_XX\Skill\VDN[2]@Status));
A

Prestei mais atenção em seu código agora e vi que realmente foi a confusão dos caminhos.

O método retornaConteudoXml(…) vai ser chamado todas as vezes que você quiser extrair o conteúdo de uma tag no seu arquivo e você passará o caminho Xpath (ver tutorial) para retornar o conteúdo daquela tag ou propriedades da tag específicos.

exemplo de um xlm simples (c:\xmlfiles\teste.xml):

<raiz>
       <andar id="Primeiro andar" numero="32">
                  <secao1>cinema</secao1>
                  <secao2>restaurantes</secao2>
       <\andar>
       <andar id="Segundo andar" numero ="33">
                    <secao1>lojas<\secao1>
                    <secao2>estacionamento<\secao2>
       <\andar>
<\raiz>

Ok, então, meu código ficaria, mais ou menos assim:

LeitorXml leitor = new LeitorXml("c:\\xmlfiles\\teste.xml");

syso ("1a linha --> " + leitor.retornaConteudoXML("raiz/andar[1]@id");
syso ("2a linha --> " + eitor.retornaConteudoXML("raiz/andar[2]/secao1");

O retorno será:

1a linha -->Primeiro andar
2a linha -->lojas

Cara… foi mal… a barra é a outra (/) e não ()… tinha muito tempo que não usava e não lembrei… foi mal mesmo.
:shock: :shock: :shock: :shock:

Não esqueça de checar o tutorial.

P

Show 5 estrelas, mas como faria para percorrer todas ocorrencias pois desse jeito eu peguei somente uma vez.

public static void main(String[] args) {
		try {
			 ManipulaXML leitor = new ManipulaXML("/VDN.xml");
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill/@Numero"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill/@Nome"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill/VDN/@Numero"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill/VDN/@Status"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill/VDN/@Label"));
		} catch (Exception e) {
			e.printStackTrace();
		}
}
P

Existe alguma forma para eu pegar a quantidade de tags para fazer dinamico esse processo harcode

System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[1]/@Numero"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[1]/@Nome"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[1]/VDN/@Numero"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[1]/VDN/@Status"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[1]/VDN/@Label"));
			 System.out.println("---------------------");
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[2]/@Numero"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[2]/@Nome"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[2]/VDN/@Numero"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[2]/VDN/@Status"));
			 System.out.println(leitor.retornaConteudoXML("VDNs_xxx/Skill[2]/VDN/@Label"));

No caso tenho 3 Skill, mas pode aumentar entendeu?

A

quantidade de Tags…

Tem sim cara… é molezinha… sopinha no mel…

Monte um método parecido com o retornaConteudoXML e no evaluate do xpath você passa o caminho XPATH completo do nodo a ser contado…

Bom… aí vai o código

return (String) xpath.evaluate("count(raiz/andar/)");

Nesse caso, pro meu exemplo, ele retornará 2.

C

Kra usa o xstream
Vai te resolver a vida com xml…
Da uma procurada num artigo aqui do guj sobre como usar ele, garanto q tu n vai t arrepender…

P

Então estou fazendo assim, mas não compila, é assim mesmo?

public String ocorrenciasTagXml(String tag){
    return (String) xpath.evaluate("count(VDNs_xxx/Skill)");

}
A

Qual erro que está dando?

O que acusa pra não compilar?

P

The method evaluate () in the type Xpath is not applicable for the arguments String

A

falha minha

return (String) xpath.evaluate("count(VDNs_Fidelity/Skill", doc, XPathConstants.STRING);

Viu… faltou o doc…

Cara… olha só… se der pau, pode ser necessário colocar outra barra depois de Skill.

Abraço.

P

Com ou sem barra no final da erro:

A

repost acidental

A

Repost acidental

A

Engraçado esse erro… bom… vamos lá… batalhar em cima dele…

<VDNs_XX>
     
     <Skill Numero="55" Nome="Real">    
         <VDN Numero="83630" Status="Ativo" Label="Desbloqueio Real"/>
         <VDN Numero="83631" Status="Desativado" Label="Perda ou Roubo Real"/>
         <VDN Numero="83632" Status="Ativo" Label="Central Real"/>
         <VDN Numero="83633" Status="Ativo" Label="Cobranca Real"/>    
     </Skill>
     
 </VDNs_XX>

Esse é o seu xml, então, para contar quantos vdn eu tenho eu passaria, naquele método, a string VDNs_XX/Skill/VDN

Caso quisesse contar quantas tags skill, passaria a string VDNs_XX/Skill

Cara, tem que funcionar, testei aqui agora com um xml meu… e funcionou direitinho.

System.out.println("Teste --- " + (String) xpath.evaluate("count(VDNS_XX/Skill/VDN)", doc, XPathConstants.STRING));

Opa… peraí… pode ser fechamento de parêntesis…()…

acho que encontrei um erro no teu… você tá recebendo a string tag no método ocorrenciaTagXML… tem uma aspas à mais depois da vírgula… olha se é isso…

P

funcionou, muito obrigado cara!

Código Final:

/**
 * 
 */
package br.com.xx.util;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;


/**
 * @author fabio.pedrosa
 *
 */
public class ManipulaXML{

	
	private Document doc; 
	private DocumentBuilder parser; 
	private XPath xpath;
	
	public ManipulaXML (String caminhoArquivoXML) throws Exception{
 		parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 		doc = parser.parse(new File(caminhoArquivoXML));
 		xpath = XPathFactory.newInstance().newXPath();
 	}
	public String retornaConteudoXML (String caminhoNodo) throws Exception{
 		return (String) xpath.evaluate(caminhoNodo, doc, XPathConstants.STRING);
 	}
	public int ocorrenciasTagXml(String tag) throws XPathExpressionException{
		return Integer.parseInt((String) xpath.evaluate("count("+tag+")", doc, XPathConstants.STRING));

	}
	public static void main(String[] args) {
		try {
			 ManipulaXML leitor = new ManipulaXML("/VDN.xml");
			 int qtd = leitor.ocorrenciasTagXml("VDNs_Fidelity/Skill");
			 for(int i=1;i<=qtd;i++){
				 if(i==1)System.out.println("SKILLS");
				 System.out.println(leitor.retornaConteudoXML("VDNs_xx/Skill["+i+"]/@Numero"));
				 System.out.println(leitor.retornaConteudoXML("VDNs_xx/Skill["+i+"]/@Nome"));
				 System.out.println(leitor.retornaConteudoXML("VDNs_xx/Skill["+i+"]/VDN/@Numero"));
				 System.out.println(leitor.retornaConteudoXML("VDNs_xx/Skill["+i+"]/VDN/@Status"));
				 System.out.println(leitor.retornaConteudoXML("VDNs_xx/Skill["+i+"]/VDN/@Label"));
				 System.out.println("---------------------");
			 }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
A

Que isso… precisa agradecer não…

Adiciona [Resolvido] no título, por gentileza… e, precisando, estamos aí pra tentar ajuda.

Criado 29 de maio de 2006
Ultima resposta 29 de mai. de 2006
Respostas 20
Participantes 3