La soluzione ignorante funziona ... almeno con i file che ho provato io.
Se qualcuno vuole provare o apportare migliorie...
Questa è versione per riga di comando.
program estraip7m;
{$mode objfpc}{$H+}
uses
Classes, FileUtil, Strutils, SysUtils,DOM, XMLRead, base64;
var
vstrm : TFilestream;
S : Tstringstream;
fPos,Lpos,count :integer;
xmlfile,p7mfiltrato : Utf8string;
j: integer;
Str : string;
XML : TXMLDocument;
begin
vstrm := TFileStream.Create(ParamStr(1), fmOpenRead);
// Apre p7m
if ExtractfileExt(ParamStr(1)) = '.p7m' then
begin
vstrm.Position:= 0;
S := TStringStream.Create('');
S.Size := vstrm.Size;
S.CopyFrom(vstrm, vstrm.Size);
S.Position := 0;
vstrm.Free;
p7mfiltrato := '';
// filtra caratteri speciali
for j := 1 to Length(s.datastring) do
if not ((s.datastring[j] in [#1..#12,#14..#30]) or (s.datastring[j] > char(127))) then
p7mfiltrato := p7mfiltrato+s.datastring[j];
// Ricerca tag xml per estrazione
FPos := Pos('<?xml version', p7mfiltrato);
LPos := Pos(':FatturaElettronica>', p7mfiltrato)+20;
Count := Lpos - FPos;
xmlfile:= MidStr(p7mfiltrato, FPos, Count);
S.Free;
// Salva xml
S := Tstringstream.Create(xmlfile);
vstrm := TFileStream.Create(StringReplace(ParamStr(1),'.xml.p7m','.xml',[rfReplaceAll]), fmCreate);
vstrm.CopyFrom(S,S.Size);
// Legge XML per attachment pdf
S.Position:= 0;
ReadXMLFile(XML, S);
s.free;
// Se esiste allegato e se PDF estrai e salva
if (XML.DocumentElement.GetElementsByTagName('Attachment').Count > 0) and (XML.DocumentElement.GetElementsByTagName('FormatoAttachment').item[0].LastChild.TextContent = 'PDF') then
begin
writeln('Estrazione pdf');
vstrm.Free;
vstrm := TFileStream.Create(StringReplace(ParamStr(1),'.xml.p7m','.pdf',[rfReplaceAll]), fmOpenWrite or fmCreate);
vstrm.Position := 0;
Str := DecodeStringBase64(XML.DocumentElement.GetElementsByTagName('Attachment').Item[0].LastChild.TextContent);
vstrm.Write(Pointer(Str)^, Length(Str) div SizeOf(Char));
end;
end
else
writeln('Tipo di File non supportato');
vstrm.Free;
end.