Read A tag that sits inside another in an . xml file with DOM API

Asked

Viewed 4,632 times

2

Take data from a tag and right after take data from a daughter tag. For example, I have 2 tags that repeat across the entire document, and I need to take data from both:

<teste:dadosLote>
<teste:numeroLote>380</unimed:numeroLote>
    <teste:dadosGuia>
       <teste:nomeBeneficiario>DIEGO AUGUSTO</teste:nomeBeneficiario>
    </teste:dadosGuia>

    <teste:dadosGuia>
       <teste:nomeBeneficiario>BRUNO HENRIQUE</teste:nomeBeneficiario>
    </teste:dadosGuia>
</teste:dadosLote>

<teste:dadosLote>
  <teste:numeroLote>381</unimed:numeroLote>
    <teste:dadosGuia>
       <teste:nomeBeneficiario>CARLOS</teste:nomeBeneficiario>
    </teste:dadosGuia>

    <teste:dadosGuia>
       <teste:nomeBeneficiario>FERNANDO</teste:nomeBeneficiario>
    </teste:dadosGuia>
</teste:dadosLote>

I can read only one Node at a time using: NodeList listaContatos = raiz.getElementsByTagName("teste:dadosGuia");. And after I get this Node I read the tags inside it as follows: contato.setNomeBeneficiario(obterValorElemento(elemento, "teste:nomeBeneficiario")); How do I read the Node <teste:dadosLote> and take your values too?

-------Code that reads the xml file-------

public List<UnimedLote> realizaLeituraXML(String arquivoXML) throws ParserConfigurationException, SAXException, IOException {
    //fazer o parse do arquivo e criar o documento XML
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(arquivoXML);

    //Passo 1: obter o elemento raiz
    Element raiz = doc.getDocumentElement();
    System.out.println("O elemento raiz é: " + raiz.getNodeName());

    //Passo 2: localizar os elementos filhos da agenda
    NodeList listaContatos = raiz.getElementsByTagName("teste:dadosLote");

    List<UnimedLote> lista = new ArrayList<>();

    //Passo 3: obter os elementos de cada elemento contato
    for (int i = 0; i < listaContatos.getLength(); i++) {
        NodeList dadosLoteChildrenNodeList = listaContatos.item(i).getChildNodes();
        //como cada elemento do NodeList é um nó, precisamos fazer o cast
        Element elementoContato = (Element) listaContatos.item(i);

        for (int j = 0; j < dadosLoteChildrenNodeList.getLength(); j++) {
            UnimedLote x = new UnimedLote();
            Node node = dadosLoteChildrenNodeList.item(j); // cuidado para nao usar o indice 'i'

            if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
                continue; // va para o proximo passo
            }

            System.out.println("o nome do no eh: '" + node.getNodeName() + "'");
            System.out.println("o conteudo do no eh: '" + node.getTextContent() + "'");

            System.out.println("");

        }

        //cria um objeto Contato com as informações do elemento contato
        UnimedLote contato = criaContato(elementoContato);

        lista.add(contato);

    }

    return lista;
}

public String obterValorElemento(Element elemento, String nomeElemento) {
    //obtém a lista de elementos
    NodeList listaElemento = elemento.getElementsByTagName(nomeElemento);
    if (listaElemento == null) {
        return null;
    }
    //obtém o elemento
    Element noElemento = (Element) listaElemento.item(0);
    if (noElemento == null) {
        return null;
    }
    //obtém o nó com a informação
    Node no = noElemento.getFirstChild();
    return no.getNodeValue();
}

public UnimedLote criaContato(Element elemento) {
    UnimedLote contato = new UnimedLote();


    /* Informaçoes do Beneficiário */
    contato.setNumeroDoLote(obterValorElemento(elemento, "teste:numeroLote"));
    contato.setNome(obterValorElemento(elemento, "teste:nomeBeneficiario"));
    return contato;
}

}

Xml snippet:

<teste:dadosLote>
          <teste:seqLote>2</teste:seqLote>
          <teste:numeroLote>392</teste:numeroLote>
          <teste:dataEnvioLote>2015-04-01</teste:dataEnvioLote>
          <teste:numeroProtocolo>392</teste:numeroProtocolo>
          <teste:valorProtocolo>3976.17</teste:valorProtocolo>
          <teste:guia>
            <teste:dadosGuia>
              <teste:seqLote>2</teste:seqLote>
              <teste:seqGuia>1</teste:seqGuia>
              <teste:numeroGuiaPrestador>4444441</teste:numeroGuiaPrestador>
              <teste:beneficiario>
                <teste:numeroCarteira>9142132133</teste:numeroCarteira>
                <teste:nomeBeneficiario>DEBORA D P DOS SANTOS</teste:nomeBeneficiario>

1 answer

1


Your xml has an element problem <teste:numeroLote> is closed with the tag <unimed:numeroLote>. I think this was copy and paste problem, correct?

Going to your question, for you to get the child elements of a Node you use the method Node#getChildNodes(). In your case, to catch the knot <teste:dadosLote> you can run the following calls:

    // ...

    NodeList dadosLoteNodeList = document.getElementsByTagName("teste:dadosLote");

    for (int i = 0; i < dadosLoteNodeList.getLength(); i++) {

        NodeList dadosLoteChildrenNodeList = dadosLoteNodeList.item(i).getChildNodes();

        int numeroDoLote = -1;
        List<String> nomeDosBeneficiarios = new LinkedList<String>();

        for (int j = 0; j < dadosLoteChildrenNodeList.getLength(); j++) {

            Node node = dadosLoteChildrenNodeList.item(j); // cuidado para nao usar o indice 'i'

            if (node.getNodeName().equals("teste:numeroLote")) {
                numeroDoLote = Integer.parseInt(node.getTextContent());
            } else if (node.getNodeName().equals("teste:dadosGuia")) {

                Node childNode = node.getFirstChild();

                while (childNode.getNextSibling() != null) {
                    childNode = childNode.getNextSibling();

                    if (childNode.getNodeName().equals("teste:nomeBeneficiario")) {
                        nomeDosBeneficiarios.add(node.getTextContent());
                    }
                }
            }
        }

        System.out.println("lote#" + numeroDoLote);
        System.out.println("beneficiarios: " + nomeDosBeneficiarios);
    }

It is recommended, when iterating on the child nodes, to check if the child is also an element type node, that is, that it is not a text - returning nodes #text on the call Node#getNomeName(). To make this check do:

    // ...

    Node node = dadosLoteChildrenNodeList.item(j);

    if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
        continue; // va para o proximo passo
    }

    // ..

For more information check the javadoc of oracle. I hope to have helped.

  • I edited with an xml snippet, only not fexei the tags because it has much content down yet.

  • I think it is not on the same level as it does not enter the if Else looking for <test:dataGuia>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.