Ancora Nodi Xml e XPath

di il
18 risposte

18 Risposte - Pagina 2

  • Re: Ancora Nodi Xml e XPath

    Precisazione:
    Provato ad unificare la funzione come al precedente post
    Se una Fattura non contiene nessun elemento nella sezione pagamento NESSUN elemento viene estratto per queste,
    e sono 160 le fatture non contenenti dati nella sezione Pagamenti.
    Nell'unica fattura contenente i dati del pagamento viene estratto tutto.

    Stanotte proseguo e faccio sapere
  • Re: Ancora Nodi Xml e XPath

    Gianni55 ha scritto:


    Set righeTrasmissione = obj.documentElement.selectNodes("//DatiTrasmissione")
                         For Each lineaTrasmissione In righeTrasmissione
                            Set CodiceDestinatario = lineaTrasmissione.selectSingleNode(".//CodiceDestinatario")
    ...
    Set righeCedente = obj.documentElement.selectNodes("//CedentePrestatore")
    
    Sarò ripetitivo, ma evidentemente non lo sono abbastanza, in quanto l'unico suggerimento netto e chiaro che sto dando fin dal principio è quello di non usare il doppio slash ("//") salvo ove sia strettamente necessario o sensato, perché quel simbolo fa partire la ricerca del nodo dalla radice del documento (!!!).

    Non capisco che senso abbia chiedere consigli su un forum, dire di essersi documentati e poi ignorare totalmente i suggerimenti che vengono dati.

    Se scrivi una cosa come questa:
    Set Cognome = lineaCedente.selectSingleNode(".//Cognome")
    di fatto stai prendendo il primo nodo che si chiama "Cognome" che è possibile incontrare dalla radice del documento.

    Nelle fatture XML (guarda lo Schema XSD relativo) vi sono diversi punti in cui l'elemento <Cognome> si ripete: con il percorso ".//Cognome" tu prenderai sempre e solo il primo!

    Quindi, in sintesi, è sbagliato, è errato, è fallace, è impreciso, non si usa!

    Lo stesso vale per tanti altri elementi in cui hai usato lo stesso approccio, ad esempio
    Set Denominazione = lineaCedente.selectSingleNode(".//Denominazione")
    Questo elemento compare sia per l'elemento RappresentanteFiscaleCessionario sia per gli elementi di tipo Anagrafica, che sono ripetuti N volte all'interno del documento (es. DatiAnagraficiCedente, DatiAnagraficiVettore, DatiAnagraficiRappresentante, DatiAnagraficiCessionario, DatiAnagraficiTerzoIntermediario).

    Se usi ".//Denominazione", andrai a prendere sempre lo stesso valore per tutti gli elementi di cui sopra, al posto dell'elemento specifico, e tra l'altro essendo una espressione che restituisce un singolo nodo cercando dalla radice del documento XML, non ha neanche senso metterlo in un ciclo come hai fatto, perché stai eseguendo N volte una iterazione che ti porta alla fine a prendere sempre e soltanto uno ed un unico valore fra quelli presenti nel documento.

    L'approccio corretto da adottare è muoversi all'interno del documento XML scendendo all'interno dei singoli nodi, esplorandone la struttura e prendendo i valori usando riferimenti relativi (NON assoluti!) per gli elementi che sono contenuti al loro interno.

    Un esempio per far capire cosa intendo. Il documento ha come radice l'elemento <FatturaElettronica>, quindi questo elemento rappresenta il contenitore di tutto ed è rappresentato dalla proprietà obj.documentElement nel tuo codice, pertanto l'elaborazione andrà scritta in modo simile al seguente:
    
    Set headerFattura = obj.documentElement.selectSingleNode("./FatturaElettronicaHeader")
    
    Set datiTrasmissione = headerFattura.selectSingleNode("./DatiTrasmissione")
    Set trasmissioneIdPaese = datiTrasmissione.selectSingleNode("./IdTrasmittente/IdPaese")
    Set trasmissioneIdCodice = datiTrasmissione.selectSingleNode("./IdTrasmittente/IdCodice")
    Set ProgressivoInvio = datiTrasmissione.selectSingleNode("./ProgressivoInvio")
    Set formatoTrasmissione = datiTrasmissione.selectSingleNode("./FormatoTrasmissione")
    Set codiceDestinatario = datiTrasmissione.selectSingleNode("./CodiceDestinatario")
    
    Set contattiTrasmittente = datiTrasmissione.selectNodes("./ContattiTrasmittente")
    For Each contattoTrasm In contattiTrasmittente
      For Each telefono In contattoTrasm.selectNodes("./Telefono")
        ' ...
      Next
      For Each email In contattoTrasm.selectNodes("./Email")
        ' ...
      Next
    Next
    
    Set pecDestinatario = datiTrasmissione.selectSingleNode("./PECDestinatario")
    If Not pecDestinatario Is Nothing Then
        ' ...
    End If
    
    '
    ' ...
    '
    
    Set bodyFattura = obj.documentElement.selectSingleNode("./FatturaElettronicaBody")
    Set datiGenerali = bodyFattura.selectSingleNode("./DatiGenerali")
    Set datiBeniServizi = bodyFattura.selectSingleNode("./DatiBeniServizi")
    
    ' ...
    
    Set datiDocumento = datiGenerali.selectSingleNode("./DatiGeneraliDocumento")
    Set tipoDocumento = datiDocumento.selectSingleNode("./TipoDocumento")
    Set divisa = datiDocumento.selectSingleNode("./Divisa")
    
    '
    ' ...
    '
    
    In conclusione, devi conoscere lo Schema del file XML della fattura e, partendo da documentElement, recuperare i singoli elementi usando selectSingleNode(), oppure usando selectNodes() se ne sono previsti da 0 a N, in base alla cardinalità descritta nel suddetto Schema. Una volta recuperato il singolo elemento, se è obbligatorio si può utilizzare direttamente, altrimenti prima occorre testare che non sia Nothing, mentre sui cicli non dovrebbe essere necessario (se gli elementi sono zero, semplicemente il ciclo For uscirà subito). Essendo che ciascun elemento va individuato in funzione dell'elemento superiore, salvati i riferimenti ai nodi salienti (vedi esempio sopra) da cui partire per recuperare i figli, usando percorsi relativi (lo dico di nuovo) e non assoluti, magari aiutandoti nell'elaborazione suddividendo il codice in funzioni ciascuna dedicata all'elaborazione di un nodo/sottonodo specifico della fattura, che a sua volta richiama altre funzioni (passando il nodo corrente come parametro) per estrarre i valori dai sottonodi e così via, fino al recupero completo delle informazioni necessarie da scrivere sul DB.

    Ciao!
  • Re: Ancora Nodi Xml e XPath

    Gianni55 ha scritto:


    Precisazione:
    Provato ad unificare la funzione come al precedente post
    Se una Fattura non contiene nessun elemento nella sezione pagamento NESSUN elemento viene estratto per queste,
    e sono 160 le fatture non contenenti dati nella sezione Pagamenti.
    Nell'unica fattura contenente i dati del pagamento viene estratto tutto.
    Ribadisco il concetto finale: il problema non è nella struttura delle funzioni, ma nel fatto che stai "navigando male" nel documento XML, usando percorsi errati che ti restituiranno valori errati in determinate occasioni a seconda del contenuto e della struttura del file XML che si presenta o nell'incontro con specifici casi particolari.

    Leggi tutta la mia spiegazione nel post precedente e l'esempio di codice.

    Ciao!
  • Re: Ancora Nodi Xml e XPath

    Chiarissimo Alka rivedo tutto e comunico.
    Intanto grazie
Devi accedere o registrarti per scrivere nel forum
18 risposte