Carregando XML com XMLHttpRequest - JavaScript

O formato XML é popular para armazenamento e transmissão de dados. Vamos explorar como carregar um documento XML em uma página web usando uma solicitação AJAX.

Como servidor, usaremos o Node.js, assim como no tema anterior, por ser uma opção simples. No entanto, você pode usar qualquer outra tecnologia de servidor ou servidor web de sua preferência.

Vamos definir uma pasta no disco rígido para o projeto, onde criaremos três arquivos:

  • index.html: a página principal da aplicação

  • users.xml: o arquivo XML com os dados

  • server.js: o arquivo da aplicação servidor, que usará Node.js

Definindo os Dados

O arquivo users.xml representará os dados a serem carregados e terá o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8" ?>
<users>
    <user name="Tom" age="39">
        <contacts>
            <email>tom@smail.com</email>
            <phone>+1234567890</phone>
        </contacts>
    </user>
    <user name="Bob" age="43">
        <contacts>
            <email>bob@tmail.com</email>
            <phone>+1334567181</phone>
        </contacts>
    </user>
    <user name="Sam" age="28">
        <contacts>
            <email>sam@xmail.com</email>
            <phone>+1434567782</phone>
        </contacts>
    </user>
</users>

Aqui, o elemento users representa um conjunto de usuários, cada um representado pelo elemento user. Para cada user, foram definidos dois atributos: name (nome do usuário) e age (idade do usuário). O elemento user também possui um elemento aninhado contacts, que representa os dados de contato do usuário nos elementos phone e email.

Definindo o Servidor

O arquivo server.js conterá o código do servidor Node.js. Definimos o seguinte código:

const http = require("http");
const fs = require("fs");

http.createServer((request, response) => {
    // se os dados XML forem solicitados
    if (request.url == "/data") {
        fs.readFile("users.xml", (_, data) => response.end(data));
    } else {
        fs.readFile("index.html", (_, data) => response.end(data));
    }
}).listen(3000, () => console.log("Servidor iniciado em http://localhost:3000"));

Vamos analisar o código. Primeiro, importamos os pacotes necessários:

const http = require("http");   // para tratar requisições
const fs = require("fs");       // para ler arquivos do disco rígido

Para criar o servidor, usamos a função http.createServer(). Esta função recebe um manipulador que é chamado sempre que o servidor recebe uma solicitação. O manipulador possui dois parâmetros: request (contém dados da solicitação) e response (gerencia o envio da resposta).

No manipulador, usamos a propriedade request.url para obter o caminho do recurso solicitado. Neste caso, se o caminho solicitado for "/data", enviamos o conteúdo de users.xml:

if (request.url == "/data") {
    fs.readFile("users.xml", (_, data) => response.end(data));
}

Para ler o arquivo, usamos a função fs.readFile. O primeiro parâmetro é o caminho do arquivo (assumindo que está na mesma pasta que o arquivo do servidor). O segundo parâmetro é uma função que é chamada após a leitura do arquivo e recebe seu conteúdo como segundo parâmetro data.

Para todas as outras solicitações, enviamos o arquivo index.html como resposta:

else {
    fs.readFile("index.html", (_, data) => response.end(data));
}

Por fim, usamos a função listen() para iniciar o servidor web na porta 3000. Assim, o servidor estará acessível em http://localhost:3000.

Carregando XML na Página Web

Para obter o arquivo users.xml do servidor, definimos o seguinte código no arquivo index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Programício</title>
</head>
<body>
<script>
const xhr = new XMLHttpRequest();
xhr.onload = () => {
    if (xhr.status == 200) {
        const xml = xhr.responseXML;
        console.log(xml);
    }
};
xhr.open("GET", "/data");              // Solicitação GET para /data
xhr.responseType = "document";         // Definindo o tipo de resposta
xhr.setRequestHeader("Accept", "text/xml");    // Aceitando apenas XML
xhr.send();                            // Enviando a solicitação
</script>
</body>
</html>

Para obter os dados, enviamos uma solicitação para o endereço /data. Para que os dados recebidos sejam automaticamente analisados como um documento XML, definimos a propriedade responseType como "document":

xhr.responseType = "document";

Além disso, é necessário definir o cabeçalho Accept como "text/xml" ou "application/xml" para aceitar apenas dados no formato XML:

xhr.setRequestHeader("Accept", "text/xml");

No manipulador do evento onload, o documento XML estará disponível através da propriedade responseXML como um objeto do tipo Document, que neste caso é simplesmente exibido no console:

xhr.onload = () => {
    if (xhr.status == 200) {
        const xml = xhr.responseXML;
        console.log(xml);
    }
};

Após definir todos os arquivos, navegamos até a pasta do servidor no console usando o comando cd e iniciamos o servidor com o comando node server.js:

C:\app>node server.js
Servidor iniciado em http://localhost:3000

Depois de iniciar o servidor, podemos acessar a página no navegador em http://localhost:3000. O JavaScript na página fará uma solicitação para o endereço /data. O servidor responderá com o conteúdo do arquivo users.xml, e o console do navegador exibirá este conteúdo:

Obtendo XML com XMLHttpRequest em JavaScript

Exibindo Dados do Documento XML na Página

Agora vamos supor que precisamos exibir os dados dos usuários do XML em uma tabela na página web. Para isso, vamos alterar o código do index.html da seguinte forma:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Programício</title>
</head>
<body>
<div id="content"></div>
<script>
const contentDiv = document.getElementById("content");

const xhr = new XMLHttpRequest();
xhr.onload = () => {
    if (xhr.status == 200) {
        const xmlDoc = xhr.responseXML;
        const table = createTable();
        // Seleciona todos os elementos user
        const users = xmlDoc.getElementsByTagName("user");
        for (let i = 0; i < users.length; i++) {
            const user = users[i];
            const userName = user.getAttribute("name");
            const userAge = user.getAttribute("age");
            const contact = user.querySelector("contacts email").textContent;
            const row = createRow(userName, userAge, contact);
            table.appendChild(row);
        }
        contentDiv.appendChild(table);
    }
};
xhr.open("GET", "/data");
xhr.responseType = "document";
xhr.setRequestHeader("Accept", "text/xml");
xhr.send();

// Cria a tabela
function createTable() {
    const table = document.createElement("table");
    const headerRow = document.createElement("tr");
    const nameColumnHeader = document.createElement("th");
    const ageColumnHeader = document.createElement("th");
    const contactColumnHeader = document.createElement("th");

    nameColumnHeader.appendChild(document.createTextNode("Name"));
    ageColumnHeader.appendChild(document.createTextNode("Age"));
    contactColumnHeader.appendChild(document.createTextNode("Contacts"));

    headerRow.appendChild(nameColumnHeader);
    headerRow.appendChild(ageColumnHeader);
    headerRow.appendChild(contactColumnHeader);
    table.appendChild(headerRow);

    return table;
}

// Cria uma linha para a tabela
function createRow(userName, userAge, userContact) {
    const row = document.createElement("tr");
    const nameColumn = document.createElement("td");
    const ageColumn = document.createElement("td");
    const contactColumn = document.createElement("td");

    nameColumn.appendChild(document.createTextNode(userName));
    ageColumn.appendChild(document.createTextNode(userAge));
    contactColumn.appendChild(document.createTextNode(userContact));

    row.appendChild(nameColumn);
    row.appendChild(ageColumn);
    row.appendChild(contactColumn);

    return row;
}
</script>
</body>
</html>

Nesse caso, carregamos a tabela na página dentro do elemento com o identificador content, que obtemos no código JavaScript no elemento contentDiv:

const contentDiv = document.getElementById("content");

Para criar a tabela, definimos duas funções auxiliares. A função createTable cria o elemento table com uma linha de cabeçalhos das colunas. A função createRow recebe como parâmetros o nome, a idade e os contatos do usuário, e cria uma linha para esses dados.

Na parte principal do código, fazemos a solicitação ao servidor. Como a resposta do servidor será um documento XML do tipo Document, podemos usar métodos padrão como getElementsByTagName ou querySelector para encontrar os elementos necessários no documento. Primeiro, selecionamos todos os elementos user:

const xmlDoc = xhr.responseXML;
const table = createTable();
// Seleciona todos os elementos user
const users = xmlDoc.getElementsByTagName("user");

Em seguida, percorremos todos os elementos user e obtemos os atributos name e age, bem como o elemento aninhado email:

for (let i = 0; i < users.length; i++) {
  const user = users[i];
  const userName = user.getAttribute("name");
  const userAge = user.getAttribute("age");
  const contact = user.querySelector("contacts email").textContent;
  const row = createRow(userName, userAge, contact);
  table.appendChild(row);
}

Para cada elemento user, criamos uma linha que é adicionada à tabela.

Dessa forma, ao acessar a página index.html, o documento XML será carregado e a tabela será criada:

Carregando XML em tabela com XMLHttpRequest em JavaScript
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com