nicolap ha scritto:
Condivido il sorgente, in Delphi 7, di un semplice programmino (per riga di comando) che
- trasforma un .xml.p7m in semplice .xml (senza verificare la firma);
- estrae eventuali allegati da una Fattura Elettronica e li salva in una cartella con lo stesso nome.
Lo ho scritto ieri sera in fretta e mancano un sacco di controlli
Va bene soprattutto ai disperati che ricevono le fatture sulla PEC e mi bombarda(va)no di telefonate perché, ovviamente, non riuscivano ad aprirle
Ciao
Nicola
FatturaElettronicaExtractor 1.0 - Nicola Perotto 2019
Usa le seguenti librerie:
JvString.pas parte di JEDI VCL http://jvcl.sourceforge.net
OpenSSLUtils.pas https://github.com/bambucode/tfacturaelectronica/tree/master/OpenSSL
"With a contribute of Univerity of Genoa (Italy) http://www.unige.it/"
Serve il file libeay32.dll che fa parte di OpenSSL.
}
Program FEExtractor;
{$APPTYPE CONSOLE}
Uses
SysUtils, JvStrings, OpenSSLUtils, XMLIntf, XMLDoc, ComObj, ActiveX, Classes;
Var
Destinazione, Estensione, NomeFile : string;
Procedure EstraiAllegati(NomeXml:string);
Var
Cartella : string;
XML : IXMLDOCUMENT;
Node1, Node2, Node3 : IXMLNODE;
i, n : integer;
Testo, Normale, NomeAllegato : string;
f : TFileStream;
begin
Cartella := ChangeFileExt(NomeXml, '');
try
CoInitializeEx(nil, COINIT_APARTMENTTHREADED); //Inizializza il sottosistema COM per poter usare le 'Interface'
XML := NewXMLDocument;
XML.Encoding := 'UTF-8';
XML.NodeIndentStr := ' '; //space *2
XML.Options := [doNodeAutoIndent]; // looks better in Editor ;)
XML.LoadFromFile(NomeXml);
//2 <1.N> <FatturaElettronicaBody>
//2.5 <0.N> <Allegati>
//2.5.1 <1.1> <NomeAttachment> xs:normalizedString 1 … 60
//2.5.2 <0.1> <AlgoritmoCompressione> xs:string 1 … 10
//2.5.3 <0.1> <FormatoAttachment> xs:string 1 … 10
//2.5.4 <0.1> <DescrizioneAttachment> xs:normalizedString 1 … 100
//2.5.5 <1.1> <Attachment> xs:base64Binary valore vincolato alla dimensione max prevista per la fattura elettronica
if CompareText(XML.DocumentElement.LocalName, 'FatturaElettronica') <> 0 then begin
writeln('Non è una Fattura Elettronica.');
Exit;
end;
Node1 := XML.DocumentElement.ChildNodes.FindNode('FatturaElettronicaBody', '');
if not Assigned(Node1) then Exit;
Node2 := Node1.ChildNodes.FindNode('Allegati', '');
if not Assigned(Node2) then Exit;
//Ci sono 1 o più allegati, li salvo nella cartella con lo stesso nome del file XML
if not DirectoryExists(Cartella) then
CreateDir(Cartella);
Cartella := Cartella + '\';
NomeAllegato := '';
n := 1;
i := 0;
while (i <= Node2.ChildNodes.Count - 1) do begin
Node3 := Node2.ChildNodes.Get(i);
if CompareText(Node3.LocalName, 'NomeAttachment') = 0 then
NomeAllegato := Node3.NodeValue;
if CompareText(Node3.LocalName, 'AlgoritmoCompressione') = 0 then ; //ignora
if CompareText(Node3.LocalName, 'FormatoAttachment') = 0 then ; //ignora
if CompareText(Node3.LocalName, 'DescrizioneAttachment') = 0 then ; //ignora
if CompareText(Node3.LocalName, 'Attachment') = 0 then begin
Testo := Node3.NodeValue;
try
Normale := B64Decode(Testo);
except
on E:Exception do begin
writeln('L''allegato ' + IntToStr(n) + ' non è codificato Base64 correttamente.');
Normale := '';
end;
end;
if (NomeAllegato <> '') and (Normale <> '') then begin
try
f := TFileStream.Create(Cartella + NomeAllegato, fmCreate);
f.Write(Normale[1], Length(Normale));
finally
FreeAndNil(f);
end;
end;
NomeAllegato := '';
Inc(n);
end; //if
Inc(i);
end; //for i
finally
XML.Active := False;
// CoUninitialize; //se lo chiamo poi si incazza!
end;
end; //EstraiAllegati
Procedure TogliFirma(Nomep7m, NomeXml:string);
Var
Reader : TPKCS7;
begin
Reader := TPKCS7.Create;
Reader.Open(Nomep7m);
Reader.SaveContent(NomeXml);
Reader.Free;
end; //TogliFirma
begin
if ParamCount <> 1 then begin
writeln('FEExtractor 1.0');
writeln('Estrae gli allegati da una fattura elettronica, eventualmente rimuovendo la firma.');
writeln('Attenzione: sovrascrive SENZA AVVISARE!');
writeln('Uso: FEExtractor nomefile');
Halt(1);
end;
NomeFile := ParamStr(1);
if not FileExists(NomeFile) then begin
writeln('Errore: il file <' + NomeFile + '> non esiste.');
Halt(2);
end;
Estensione := ExtractFileExt(NomeFile);
if (CompareText(Estensione, '.xml') = 0) then begin
EstraiAllegati(NomeFile);
end else if (CompareText(Estensione, '.p7m') = 0) then begin
Destinazione := ChangeFileExt(NomeFile, '');
AppStartup;
TogliFirma(NomeFile, Destinazione);
EstraiAllegati(Destinazione);
end else begin
writeln('Errore: il file deve essere .xml oppure .xml.p7m');
Halt(2);
end;
Halt(0);
end.
Edit: la roba qua sopra è vecchia. Link aggiornato FEextract140.zip