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 eStevo2734
      Pequei esse código, porém não funciona por nada pela minha capacidade que não é muita em PHP, já mudei ele de todas as formas possível e não funciona.
       
      <?php if(!empty($_FILES['xml']['tmp_name'])){ $arquivo = new DomDocument(); $arquivo->load($_FILES['xml']['tmp_name']); //var_dump($arquivo); $linhas = $arquivo->getElementsByTagName("processo"); //var_dump($linhas); $primeira_linha = true; foreach($linhas as $linha){ if($primeira_linha == false){ // pegar o valor natureza="Produtos e/ou Serviço" no elemento <marca> $nome = $linha->getElementsByTagName("nome")->item(0)->nodeValue; echo "Nome: $nome <br>"; $email = $linha->getElementsByTagName("status")->item(1)->nodeValue; echo "Status: $email <br>"; echo "<hr>"; } $primeira_linha = false; } } ?>  
      O arquivo em XML é beemmm longo
      <?xml version="1.0" encoding="UTF-8" ?> <revista numero="2620" data="23/03/2021"> <processo numero="922151156" data-deposit <despachos> <despacho codigo="IPAS009" nome="Publ </despachos> <titulares> <titular nome-razao-social="HERIK DE </titulares> <marca apresentacao="Mista" natureza="P <nome>SOTEN</nome> </marca> <classes-vienna> <classe-vienna codigo="27.5.1" edicao <classe-vienna codigo="28.3" edicao=" <classe-vienna codigo="26.2.7" edicao <classe-vienna codigo="29.1.15" edica </classes-vienna> <lista-classe-nice> <classe-nice codigo="41"> <especificacao>Agente artístico; li <status>Pendente</status> </classe-nice></lista-classe-nice> <procurador>TENAX SERVIÇOS DE CONSULTOR </processo> <processo numero="920178898"> <despachos> <despacho codigo="IPAS029" nome="Defe </despachos> <titulares> <titular nome-razao-social="DEIVISSON </titulares> <lista-classe-nice> <classe-nice codigo="25"> <especificacao>Bandanas;Bermudas;Bo <status>Deferida</status> </classe-nice> </lista-classe-nice> </processo> Os valores que estou tentando pegar são <nome>
      <status>. Mas também queria tentar pegar os
      valores nome-razao-social="..." e natureza. Penso que
      pode ter algo a ver com o tamanho do arquivo que é um
      pouco maior do que o habitual, girando em torno de
      30 MB e no total vão ter que tirar as informações 22 109
      que é o número de vezes que esse modelo de exemplo
      se repete no documento Mas como disse não sei muito
      sobre PHP é uma suposição)...
    • By joeythai
      Boa tarde pessoal,
       
      Tenho uma API para enviad dados via XML, eu salvo esse xml em um arquivo físico, os dados no arquivo físico me retornam 2 registros com todas as TAGs certinho, porém, quando eu pego a url e mando no browser, esses registros duplicam, alguém sabe o porque disso ? Estou utilizando laravel e a biblioteca DomDocument do PHP. O código esse abaixo:
       
      <code>
      <?php   namespace App\Http\Controllers\API\V1\Integracao;   use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\ValidationException; use App\Services\ToArray; use App\Exceptions\ApiException; use App\Http\Controllers\AppBaseController; use Illuminate\Support\Str; use App\Model\MySql\Site\IntegracaoModel as Integracao; use App\Model\MySql\Site\AuxFotosModel; use DOMDocument;   /** * * Classe criada para retornar informações dos imóveis do site da Sodré * e integrar com o Zap e Viva Real * */   class IntegracaoController extends AppBaseController { private $infos; private $integracao; private $urlImagem = "https://fotos.sodresantoro.com.br/fotos.imoveis/";   public function __construct(Integracao $integracao) { $this->integracao = $integracao; }   public function index() {   $dadosImoveis = $this->integracao->imoveis();   #versao do encoding xml $dom = new DOMDocument("1.0", "UTF-8");   #retirar os espacos em branco $dom->preserveWhiteSpace = false;   #gerar o codigo $dom->formatOutput = true;   #criando o nó principal (root) $root = $dom->createElement("ListingDataFeed"); $domAttrXMLNS = $dom->createAttribute("xmlns"); $domAttrXMLNS->value = 'http://www.vivareal.com/schemas/1.0/VRSync'; $domAttrXMLNSXSI = $dom->createAttribute("xmlns:xsi"); $domAttrXMLNSXSI->value = "http://www.w3.org/2001/XMLSchema-instance"; $domSchemaLocation = $dom->createAttribute("xsi:schemaLocation"); $domSchemaLocation->value = "http://www.vivareal.com/schemas/1.0/VRSync";   #nó filho $listings = $dom->createElement("Listings");   foreach ($dadosImoveis as $imoveis) {   $listing = $dom->createElement("Listing"); $details = $dom->createElement("Details"); $media = $dom->createElement("Media");   foreach ($imoveis->imagens as $key => $imagem) {   $this->infos['imagem'] = $this->urlImagem . $imagem->nome; $item = $dom->createElement("Item", $this->infos['imagem']);   #adiciona atributos nos elementos $domAttrImage = $dom->createAttribute("medium"); $domAttrImage->value = "image";   $domAttrCap = $dom->createAttribute("caption"); $domAttrCap->value = "img" . $key++;   $domAttrPrimary = $dom->createAttribute("primary"); $domAttrPrimary->value = "true"; $item->appendChild($domAttrCap); $item->appendChild($domAttrImage); $media->appendChild($item); } $this->infos['lance_inicial'] = $imoveis->vl_lanceinicial; $this->infos['title'] = $imoveis->title; $this->infos['descricao'] = $imoveis->descricao; $this->infos['lote_id'] = $imoveis->lote_id; $this->infos['endereco'] = $imoveis->Endereco; $this->infos['imagem'] = '';   //Faço o explode para poder fazer o envio(API não aceita casas decimais) //Para consultar: https://developers.grupozap.com/feeds/vrsync/elements/details/#list-price $preco = explode('.', $this->infos['lance_inicial']);   $listPrice = $dom->createElement("ListPrice", $preco[0]); $description = $dom->createElement("Description", htmlspecialchars(str_limit($this->infos['descricao'], 2000)));   $title = $dom->createElement("Title", $this->infos['title']); $listingID = $dom->createElement("ListingID", $this->infos['lote_id']); $transactionType = $dom->createElement("TransactionType", "For Sale"); $usageType = $dom->createElement("UsageType", "Residential"); $propertyType = $dom->createElement("PropertyType", "Residential / Apartment");   #adiciona os nós $details->appendChild($usageType); $details->appendChild($propertyType); $details->appendChild($description); $details->appendChild($listPrice);   $listing->appendChild($title); $listing->appendChild($listingID); $listing->appendChild($transactionType); $listing->appendChild($details); $listing->appendChild($media);   $listings->appendChild($listing); }   $root->appendChild($listings); $root->appendChild($domAttrXMLNS); $root->appendChild($domAttrXMLNSXSI); $root->appendChild($domSchemaLocation);   $dom->appendChild($root);   # Para salvar o arquivo, descomente a linha $dom->save("listagem-imoveis.xml");   #cabeçalho da página #header("Content-Type: text/xml"); # imprime o xml na tela print $dom->saveXML(); return response($dom->saveXML()); }   public function download() { return response()->file(public_path('listagem-imoveis.xml', 'Imóveis')); } } </code>
    • By wagner9
      Olá companheiros,
       
      Preciso de ajuda para conseguir implementar um Feed de Notícias de um site parceiro em meu site. O pessoal do site parceiro me enviou os arquivos .xml, mas não consegui descobrir como implementar eles no meu site.
       
      Se alguem puder me ajudar, fico grato.
    • By manigold
      Estou com um pequeno problema nessa parte:
      $monsters = simplexml_load_file($otdir . '/data/monster/monsters.xml') or die('<b>Could not load monsters!</b>'); foreach($monsters->monster as $monster) { $loot = simplexml_load_file($otdir . '/data/monster/' . $monster['file']); if($loot) { if($item = $loot->loot->item){ A pagina mostra a lista de items corretamente mas se eu tenho um item dentro de outro item ,como nesse exemplo:
      <loot> <item id="2148" countmax="100" chance="33750" /> <item id="2148" countmax="100" chance="33750" /> <item id="2672" countmax="5" chance="80000" /> <item id="7399" chance="80" /> <item id="2392" chance="1428" /> <item id="2033" chance="3190" /> <item id="2547" countmax="7" chance="6700" /> <item id="5948" chance="3040" /> <item id="1987" chance="100000"> <!-- bag --> O PROBLEMA É NESSA PARTE <item id="5882" chance="5920" /> <item id="2498" chance="888" /> <item id="7378" countmax="3" chance="8800" /> <item id="2146" chance="5300" /> <item id="2414" chance="1500"/> <item id="2528" chance="2333" /> <item id="7402" chance="2000" /> <item id="2492" chance="730" /> </item> </loot> Os items dentro do item com id 1987 não são mostrados .
      Me desculpem se a explicação não esta muito boa , não entendo nada de php e xml ,eu agradeço se alguem puder me ajudar.
    • By neoandrevictor
      Bom dia,
       
      Como faço para gerar um arquivo .doc (Microsoft Word) através de javascript com margens customizadas? Sei que para gerar o css corretamente tenho que gerar inline mas não consigo definir a margem de jeito algum.
       
      Poderiam me ajudar por gentileza?
×

Important Information

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