tafazzi87
tafazzi87

Reputation: 449

Edit an XML file on a FTP folder

I've to add a new child on an XML tag using PHP.

I've created a little PHP script to open FTP connection to the folder where is XML file to edit and use SimpleXML to edit and add new child to that file.

<html lang="it">
    <head>
        <title>Modifica Fattura</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    </head>
    <body style="text-align: center;">
        <h2 class="text-center">Modifica</h2>
            <form style="display: inline-block;" method="post">
            <input type="text" name="nome_file" placeholder="Inserisci il nome del file">
            <br>
            <select name="banca">
                <option value="000000936">INT</option>
                <option value="000092413">BIO</option>
            </select>
            <br>
            <input type="submit" name="invia" value="Modifica XML">
        </form>
        <?php
        $ftp_server = "xxx.xxx.xxx.xxx";
        $ftp_username = "xxxxxxx";
        $ftp_password = "xxxxxxx";
        $conn_ftp = ftp_connect($ftp_server) or die ("Non posso connettermi al server FTP");
        $login_ftp = ftp_login($conn_ftp,$ftp_username,$ftp_password);
        if ($login_ftp){
            if (isset($_POST['nome_file'])) {
                $nome_file = $_POST['nome_file'];
                $fp = fopen($nome_file,'w');
                $banca = $_POST ['banca'];
                $xml = simplexml_load_file($nome_file);
                if ($xml){
                    $fatt_primo = $xml->FatturaElettronicaBody;
                    $pagamento = $fatt_primo->addChild('DatiPagamento');
                    $dettaglio_pagamento = $pagamento->addChild('DettaglioPagamento');
                    $dettaglio_pagamento->addChild('IBAN', $banca);
                    $xml->asXML($nome_file);
                }
                fclose($fp);
            }
        }
        ?>
    </body>
</html>

I expect that code to append two tags inside <FatturaElettronicaBody>.


I've that XML:

<?xml version="1.0" encoding="UTF-8"?>
<p:FatturaElettronica xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" versione="FPR12" xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd">
  <FatturaElettronicaHeader>
    <DatiTrasmissione>
      <IdTrasmittente>
        <IdPaese>IT</IdPaese>
        <IdCodice>1122</IdCodice>
      </IdTrasmittente>
      <ProgressivoInvio>2</ProgressivoInvio>
      <FormatoTrasmissione>FPR12</FormatoTrasmissione>
      <CodiceDestinatario>SSDPV</CodiceDestinatario>
      <ContattiTrasmittente>
        <Telefono>1223111</Telefono>
        <Email>[email protected]</Email>
      </ContattiTrasmittente>
    </DatiTrasmissione>
    <CedentePrestatore>
      <DatiAnagrafici>
        <IdFiscaleIVA>
          <IdPaese>IT</IdPaese>
          <IdCodice>88855443</IdCodice>
        </IdFiscaleIVA>
        <Anagrafica>
          <Denominazione>REREWRWE</Denominazione>
        </Anagrafica>
        <RegimeFiscale>RF17</RegimeFiscale>
      </DatiAnagrafici>
      <Sede>
        <Indirizzo>VIA PIPPO</Indirizzo>
        <CAP>06000</CAP>
        <Comune>ROMA</Comune>
        <Provincia>RM</Provincia>
        <Nazione>IT</Nazione>
      </Sede>
      <Contatti>
        <Telefono>12321321</Telefono>
        <Email>[email protected]</Email>
      </Contatti>
      <RiferimentoAmministrazione>7</RiferimentoAmministrazione>
    </CedentePrestatore>
    <CessionarioCommittente>
      <DatiAnagrafici>
        <IdFiscaleIVA>
          <IdPaese>IT</IdPaese>
          <IdCodice>00123321321</IdCodice>
        </IdFiscaleIVA>
        <CodiceFiscale>00123321321</CodiceFiscale>
        <Anagrafica>
          <Denominazione>FRITTTROP</Denominazione>
        </Anagrafica>
      </DatiAnagrafici>
      <Sede>
        <Indirizzo>VIA ELSI</Indirizzo>
        <CAP>00100</CAP>
        <Comune>ROMA</Comune>
        <Provincia>RM</Provincia>
        <Nazione>IT</Nazione>
      </Sede>
    </CessionarioCommittente>
  </FatturaElettronicaHeader>
  <FatturaElettronicaBody>
    <DatiGenerali>
      <DatiGeneraliDocumento>
        <TipoDocumento>TD01</TipoDocumento>
        <Divisa>EUR</Divisa>
        <Data>2019-04-08</Data>
        <Numero>12</Numero>
        <ImportoTotaleDocumento>384.30</ImportoTotaleDocumento>
        <Causale>Fattura</Causale>
      </DatiGeneraliDocumento>
    </DatiGenerali>
    <DatiBeniServizi>
      <DettaglioLinee>
        <NumeroLinea>1</NumeroLinea>
        <Descrizione>TEST</Descrizione>
        <PrezzoUnitario>250.00</PrezzoUnitario>
        <PrezzoTotale>250.00</PrezzoTotale>
        <AliquotaIVA>22.00</AliquotaIVA>
      </DettaglioLinee>
      <DatiRiepilogo>
        <AliquotaIVA>22.00</AliquotaIVA>
        <ImponibileImporto>315.00</ImponibileImporto>
        <Imposta>69.30</Imposta>
        <EsigibilitaIVA>I</EsigibilitaIVA>
      </DatiRiepilogo>
    </DatiBeniServizi>
  </FatturaElettronicaBody>
</p:FatturaElettronica>


and i want to append inside another two tags like that :

<FatturaElettronicaBody>
  <DatiPagamento>
    <DettaglioPagamento>
      <IBAN>12312312</IBAN>
    </DettaglioPagamento>
  </DatiPagamento>
</FatturaElettronicaBody>

Upvotes: 1

Views: 1036

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202242

Opening FTP connection does not make other functions magically access files on the FTP server. They still work with local files. Neither does your fopen have any effect on the rest of the code.


SimpleXML functions do support URL wrappers. If you have URL wrappers enabled in PHP, you can simply use an FTP URL in simplexml_load_file and asXML calls. Though FTP URL wrapper needs to set context option overwrite to allow overwriting an existing file. And SimpleXML does not allow context options. So you have to delete the existing file before saving it (the unlink call).

$ftp_server = "ftp.example.com";
$ftp_username = "username";
$ftp_password = "password";

if (isset($_POST['nome_file'])) {
    $nome_file = $_POST['nome_file'];
    $url = "ftp://$ftp_username:$ftp_password@$ftp_server/$nome_file";
    $banca = $_POST ['banca'];
    $xml = simplexml_load_file($url);
    if ($xml){
        $fatt_primo = $xml->FatturaElettronicaBody;
        $pagamento = $fatt_primo->addChild('DatiPagamento');
        $dettaglio_pagamento = $pagamento->addChild('DettaglioPagamento');
        $dettaglio_pagamento->addChild('IBAN', $banca);
        unlink($url);
        $xml->asXML($url);
    }
}

This is easy, but inefficient. It involves three connections to the FTP (for reading, deleting and writing).

Also note that if your credentials include some special symbols, you need to URL-encode them.


For a more efficient solution, download the XML to memory, edit it in memory and upload it back.

Some references for that:

Upvotes: 1

Related Questions