Jump to content
Omar~

Manipular XML com php

Recommended Posts

Blz?!

Então, vou ser direto. Fiz esse arquivo xml aqui para servir de exemplo para a dúvida:

Spoiler

<?xml version="1.0" encoding="UTF-8"?>
<meu_xml>
    <indice_a>
        <titulo>
            Título 1
        </titulo>
        <descricao>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </descricao>
        <tipo>
            teste 1
        </tipo>
    </indice_a>

    <indice_b>
        <titulo>
            Título 2
        </titulo>
        <descricao>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        </descricao>
        <tipo>
            teste 2
        </tipo>
    </indice_b>
</meu_xml>

 

 

O negócio é o seguinte: Como no exemplo tenho 2 entradas nesse arquivo, como eu faria para manipular elas, até mesmo criar novas ou apagar editando o arquivo?

Porque enquanto a ler os dados sempre fiz, mas daí editar o arquivo estou curioso como proceder

 

Só por mostrar mesmo assim é o exemplo de leitura:

Spoiler

<?php
$file = '/meu_xml.xml';
$xml = simplexml_load_file($file);
if (file_exists($file) && count($xml->$getA)) {
    foreach ($xml->$getA as $item) {
         $item->titulo;
         $item->descricao;
    }
}

 

 

Obtenho o valor do índice vindo pelo $_GET o exibo os valores.

A questão é que esses dados dificilmente serão editados no website, mas serão sim. E para evitar re-enviar o arquivo ou mesmo usar o banco para uma coisa que "raramente" será modificada, estou pensado em realizar isso.

 

Re-escrever todo arquivo? Ou teria uma forma de manipular cada índice?

Share this post


Link to post
Share on other sites

Fala Omar. Tem como você manipular cada índice, tem que usar o DOMDocument pra realizar a alteração. Fiz um exemplo aqui que vai te dar um norte legal:

<?php
$file = 'meu_xml.xml';
$xml = simplexml_load_file($file);

$dom = new DOMDocument("1.0");

// carrega meu_xml.xml
$dom->load($file);
// pega todos os nodes
$root = $dom->documentElement;
// pega o node que você quer percorrer
$indices = $root->getElementsByTagName('indice_a');

foreach ($indices as $indice) {

	// ===========================================================================//
	// 1. aqui você cria um novo node
    $foo_node = $dom->createElement('foo_node', 'aqui vai o valor do novo node');
	// 2. aqui você adiciona o novo node dentro do node indice_a
    $indice->appendchild($foo_node);
    // ===========================================================================//

    // ===========================================================================//
    // aqui você cria um novo node dentro de outro
    // 1. cria o novo node ou pega um já existente
    $baa_node = $dom->createElement('baa_node');
    // 2. adiciona o novo node dentro do node indice_a
    $indice->appendchild($baa_node);
    // 3. adiciona mais um node dentro do node que foi criado anteriormente (baa_node)
    $baa_node->appendchild($dom->createElement("blabla_node", "aqui vai o valor do novo node"));
    // ===========================================================================//

    // ===========================================================================//
    // 1. aqui você pega um node já existente que queira manipular
    $titulo = $indice->getElementsByTagName('titulo')->item(0);
 	// 2. manipule trocando o valor do node, use o ->nodeValue
    $titulo->nodeValue = "alou alouuu";
    // ===========================================================================//

    // ===========================================================================//
    // aqui você pega o conteúdo do node
    // 1. pode usar ->textContent ou ->nodeValue
    $tipo = $indice->getElementsByTagName('tipo')->item(0)->textContent;
    echo $tipo;
    // ===========================================================================//

    // ===========================================================================//
    // 1. descomenta aqui pra você remover o node "descricao"
    // $descricao = $indice->getElementsByTagName('descricao')->item(0);
    // $descricao->parentNode->removeChild($descricao);
    // ===========================================================================//
    
}
// salva as alterações
$dom->save($file);

 

  • +1 1

Share this post


Link to post
Share on other sites

Valeu @BrunoBit vou dar uma olhada melhor

Porque para criar novo índice tenho que fazer:

Buscar todos índices atuais em array > adicionar novo na array > re-salvar o arquivo inteiro.

Para apagar:

Buscar todos índices atuais em array > apagar o índice em questão > re-criar a array > re-salvar com a nova array.

Para editar segue o mesmo esquema de apagar e editar juntos. Tenho que pegar o índices salvar-lo separadamente da array > armazenar então array em um VAR > fazer a edição > inserir o novo índice na VAR > re-fazer o array inicial > re-escrever todo arquivo novamentente.

Share this post


Link to post
Share on other sites

Nesse exemplo que dei dá pra fazer isso, percorrer pelos array, apagar, reescrever, por isso separei os exemplos em blocos. Outro detalhe que esqueci de colocar foi a indentação. Pra indentar o xml no arquivo é só acrescentar essas linhas no início:

$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;

Pq se não vai ficar um grudado no outro, aí pra ler fica complicado.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By TaisStream
      Como configurar essa query com inner join, no arquivo .xml?
      Me ajudem pf eu comecei mas estou perdida,  pesquisei já vi algo de /root... mas minha query esta diferente, nao sei se falta algo
       
       
      QUERY ATUAL:
      set mapreduce.job.queuename=low_relatorios; 
      set mapreduce.job.max.split.locations=100;
      SELECT a.num_msisdn,
             a.max_date
      FROM fact.dw_f_rcrg_gems_rate_subsc t
      INNER JOIN
        (SELECT num_msisdn,
                MAX(dat_operacao) AS max_date
         FROM fact.dw_f_rcrg_gems_rate_subsc
         WHERE (ref_date)>=$startdate
           AND ref_date<=$finaldate
           AND ide_plano_tarifario_atual IN (48,
                                             50,
                                             51,
                                             52,
                                             53,
                                             59,
                                             61,
                                             62,
                                             63,
                                             67,
                                             73,
                                             74)
         GROUP BY num_msisdn)a ON a.num_msisdn = t.num_msisdn
      AND a.max_date = t.dat_operacao
      WHERE ref_date>=$startdate
      AND ref_date<=$finaldate;
       
      QUERY CONFIGURANDO NO XML: 
       
          <value><![CDATA[[
      INSERT
              overwrite TABLE fact.dw_f_rcrg_gems_rate_subsc t 
              (
                      a.num_msisdn,
                      a.max_date
              )
      (SELECT
          INNER JOIN
      SELECT      
              MAX(dat_operacao) AS max_date;
      FROM fact.dw_f_rcrg_gems_rate_subsc) a
         WHERE (ref_date)>='$startdate'
           AND ref_date<=$'finaldate'
           AND ide_plano_tarifario_atual IN (48,
                                             50,
                                             51,
                                             52,
                                             53,
                                             59,
                                             61,
                                             62,
                                             63,
                                             67,
                                             73,
                                             74)
         GROUP BY num_msisdn)a ON a.num_msisdn = t.num_msisdn
                  AND a.max_date = t.dat_operacao
      WHERE ref_date>='$startdate'
      AND ref_date<=$finaldate;]]>
      </value>
       
       
      Poderiam me ajudar por favor, sou estagiario na area e ainda estou aprendendo.
    • By mjf2004
      Alguém poderia me ajudar com a solução dessa questão abaixo?
       
      Dado o seguinte esquema relacional para um banco de dados de uma academia , escreva uma definição DTD que do seu ponto de vista mapeie a estrutura desse banco de dados para um banco de dados XML.

      Alunos(RG, Nome, Endereço, Telefone, Sexo, Idade)
      Instrutores(RG, Nome, Endereço, Titulação)
      Turmas(Numero, Atividade, Horário, NoVagas,
      RGInstrutor ref Instrutores(RG) , RGMonitor ref Alunos(RG)
      Matricula(RG ref Alunos(RG), Numero ref Turmas(Numero), Ausências)
    • By sronze
      Ola estou com um problema em JavaScript
      O objetivo e digitar um ID/Nome em um input e ele buscar em um arquivo XML fazendo autocomplete e preencher outros dois inputs com os atributos associado ao ID/Nome da base XML.
       
      GIF de exemplo, obs(exatamente oque pretendo fazer): http://blog-media.chromaticsites.com.s3.amazonaws.com/google-places-autocomplete-3/autocomplete-error.gif
       
      Link do XML: https://www.w3schools.com/js/cd_catalog.xm
       
      Segue meu código:
      <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> </head> Nome:<input id="idInput"> UF:<input id="idInput02"> Ano:<input id="idInput03"> <script> var ValorXML1 = []; $(document).on('keyup' , '#idInput' ,function(){ var keyvalue = $("#idInput").val(); var xhttp; xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { ValorXML1 = []; CaregarXML(this , keyvalue); } }; xhttp.open("GET", "https://www.w3schools.com/js/cd_catalog.xml", true); xhttp.send(); }); function CaregarXML(xml , key) { var x, i, xmlDoc , key; xmlDoc = xml.responseXML; x = xmlDoc.getElementsByTagName("TITLE"); var cont = 0; for (i = 0; i < x.length; i++) { var valor = x[i].childNodes[0].nodeValue.trim(); var pattern = valor.substring(0 , key.length); if(key.toUpperCase() == pattern.toUpperCase() && cont < 5){ ValorXML1.push(valor); cont++; } } $("#idInput").autocomplete({ source: ValorXML1 }); } $( function() { $( "#idInput" ).autocomplete({ source:ValorXML1 }); }); </script>  
    • By Fernando Rafael
      Olá a todos, atualmente estou quebrando a cabeça com 3 campos da geração do XML de NFCE/NFE, são eles:   <SignatureValue> ,  <DigestValue>   e  <X509Certificate>, como  faço para gerar esses 3 campos?
       
      Procurei na internet, mas não achei nada que me ajude, gostaria de fazer 100% com php e de preferência  manualmente (sem a utilização de classes prontas na qual é difícil de entender o código).
       
      Já tenho o certificado em PFX, e já gerei um certificado do tipo PEM.
       
      OBS 1: não precisam explicar ou mandar códigos de como inserir o conteúdo gerado nas tags <SignatureValue>  e  <X509Certificate>.
       
      OBS 2: O campo <DigestValue>  notei em alguns fóruns que é um retorno da Sefaz, é correto isso?
       
      ,
    • By edionas
      como posso exibir os dados do arquivo
      http://api.tcm.ce.gov.br/sim/1_0/municipios.xml
      em uma tabela?
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.