• 0 voto(i) - 0 media
  • 1
  • 2
  • 3
  • 4
  • 5
XML e Fattura Elettronica
#1
Premetto che sto cercando di utilizzare la libreria eInvoice4D del fantastico gruppo Delphi Force per leggere le fatture elttroniche dal loro formato XML.
Non mi legge le mie fatture ed ho trovato un "inghippo?" nella libreria (o nel suo uso) per legger l'XML (di cui non sono però molto ferrato)...
Espongo il problema:
La mia fattura non viene letta dalla libreria perchè ha un prefisso (ed un Namespace) sull'item "FatturaElettronica" ("ns0:" che indirizza al namespace "http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2").
Nella libreria trovo un esempio di fattura elettronica anch'essa con un prefisso ("p:") e vedo che viene letta solo perchè viene pulito tale prefisso direttamente dall'XML prima di leggerlo con le seguenti linee di codice:
  LEpuratedStringXML := StringReplace(AStringXML, '<p:', '<', [rfReplaceAll, rfIgnoreCase]);
  LEpuratedStringXML := StringReplace(LEpuratedStringXML, '</p:', '</', [rfReplaceAll, rfIgnoreCase]);

Se aggiungo anche linee di codice simili per il mio prefisso, poi leggo anche la mia fattura elettronica, ma vorrei farlo con comandi XML invece che con uno StringReplace sull'XML e qui mi sono incartato....


Se prima faccio:
  LNodeElement := LDocument.ChildNodes.FindNode('FatturaElettronica');
trovo il nodo indipendentemente dal Namespace e riesco a leggere sia il prefisso che il NameSpaceURI:
LNodeElement.Prefix (che mi viene "ns0")
LNodeElement.NamespaceURI (che mi viene 'http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2')

Ma poi se faccio il comando GetDocBinding NON riesco in nessun modo ad abbinare il nodo "FatturaElettronica" con tale prefisso e tale NameSpaceURI!
Credo di aver provato un po' tutte le combinazioni tipo:
  Result := LoadXMLData(LNodeElement.XML).GetDocBinding(LNodeElement.Prefix+':FatturaElettronica', TeiInvoiceEx, LNodeElement.NamespaceURI) as IeiInvoiceEx;
senza che riesca a fargli trovare il nodo con il prefisso.

Altra strada, fare il GetDocBinding sul nodo trovato (LNodeElement), ma non riesco a fare nemmeno questo e non capisco perchè (o forse non so farlo io o forse non è memmeno possibile, boh)...
Aiuto!

Nel frattempo ho "aggirato" il problema con la seguente modifica in: DForce.ei.Invoice.Factory:

Era:

class function TeiInvoiceFactory.InternalNewInvoiceFromString(const AStringXML: String): IeiInvoiceEx;
var
  LEpuratedStringXML: String;
begin
  LEpuratedStringXML := StringReplace(AStringXML, '<p:', '<', [rfReplaceAll, rfIgnoreCase]);
  LEpuratedStringXML := StringReplace(LEpuratedStringXML, '</p:', '</', [rfReplaceAll, rfIgnoreCase]);
  Result := LoadXMLData(LEpuratedStringXML).GetDocBinding('FatturaElettronica', TeiInvoiceEx, TargetNamespace) as IeiInvoiceEx;
end;

Ho fatto:

class function TeiInvoiceFactory.InternalNewInvoiceFromString(const AStringXML: String): IeiInvoiceEx;
var
  LEpuratedStringXML: String;
  LDocument: IXMLDocument;
  LNodeElement, LNode: IXMLNode;
begin
  LDocument := TXMLDocument.Create(nil);
  LDocument.LoadFromXML(AStringXML);
  { Find a specific node. }
  LNodeElement := LDocument.ChildNodes.FindNode('FatturaElettronica');

  if LNodeElement.Prefix<>'' then
  Begin
    LEpuratedStringXML := StringReplace(AStringXML, '<'+LNodeElement.Prefix+':', '<', [rfReplaceAll, rfIgnoreCase]);
    LEpuratedStringXML := StringReplace(LEpuratedStringXML, '</'+LNodeElement.Prefix+':', '</', [rfReplaceAll, rfIgnoreCase]);
  End
  Else
    LEpuratedStringXML:=AStringXML;
  Result := LoadXMLData(LEpuratedStringXML).GetDocBinding('FatturaElettronica', TeiInvoiceEx, TargetNamespace) as IeiInvoiceEx;
end;
  Cita messaggio
#2
Passo avanti...

Invece di fare:
class function TeiInvoiceFactory.InternalNewInvoiceFromString(const AStringXML: String): IeiInvoiceEx;
var
LEpuratedStringXML: String;
begin
LEpuratedStringXML := StringReplace(AStringXML, '<p:', '<', [rfReplaceAll, rfIgnoreCase]);
LEpuratedStringXML := StringReplace(LEpuratedStringXML, '</p:', '</', [rfReplaceAll, rfIgnoreCase]);
Result := LoadXMLData(LEpuratedStringXML).GetDocBinding('FatturaElettronica', TeiInvoiceEx, TargetNamespace) as IeiInvoiceEx;
end;

Faccio:
class function TeiInvoiceFactory.InternalNewInvoiceFromString(const AStringXML: String): IeiInvoiceEx;
var
LDocument: IXMLDocument;
LNodeElement: IXMLNode;
begin
LDocument := TXMLDocument.Create(nil);
LDocument.LoadFromXML(AStringXML);
{ Find a specific node. }
LNodeElement := LDocument.ChildNodes.FindNode('FatturaElettronica');
Result := LoadXMLData(AStringXML).GetDocBinding('FatturaElettronica', TeiInvoiceEx, LNodeElement.NamespaceURI) as IeiInvoiceEx;
end;

ed il nodo lo leggo, il problema ora è che non riesco a leggere nel namespace corretto i sottonodi:
procedure TXMLFatturaElettronicaType.AfterConstruction;
begin
RegisterChildNode( 'FatturaElettronicaHeader', TXMLFatturaElettronicaHeaderType);
RegisterChildNode('FatturaElettronicaBody', TXMLFatturaElettronicaBodyType);
RegisterChildNode('Signature', TXMLSignatureType_ds);
FFatturaElettronicaBody := CreateCollection(TXMLFatturaElettronicaBodyTypeList, IXMLFatturaElettronicaBodyType,
'FatturaElettronicaBody') as IXMLFatturaElettronicaBodyTypeList;
inherited;
end;

Vorrei fare anche qui lo stesso trucco, ma non riesco a trovare l'XML da cui fare la ricerca generica del nodo!!!
  Cita messaggio


Vai al forum:


Utenti che stanno guardando questa discussione: 2 Ospite(i)