giovedì 24 novembre 2016

Parsing XML with C# And LINQ Microsoft Framework 4.0

Ciao a tutti,

come ci suggerisce il titolo del post, oggi illustrerò un modo comodo per leggere un file ( oppure una stringa ) contenente un messaggio XML per utilizzarlo all'interno del nostro programma......

Innanzitutto, prendiamo un file XML

<XML_NUMORDINE>
    <INFORMAZIONI>
        <CODICE_PREVENTIVO>2016O000000470</CODICE_PREVENTIVO>
        <DATA_AUTORIZZAZIONE>2016-12-01</DATA_AUTORIZZAZIONE>
        <NUMERO_ORDINE>1</NUMERO_ORDINE>
        <DATA_ORDINE>2016-12-01</DATA_ORDINE>
    </INFORMAZIONI>
    <INFORMAZIONI>
       ...
   </INFORMAZIONI>
    <INFORMAZIONI>
     ...
    </INFORMAZIONI>
    <INFORMAZIONI>
     ...
    </INFORMAZIONI>
</XML_NUMORDINE>


La necessità è, come si può immaginare, quella di ricreare un vettore o lista contenente tutti i campi racchiusi nel tag <INFORMAZIONI/>.

Per far ciò utilizzeremo Linq, innanzitutto una classe di comodo che rappresenta i dati :

      public class ItemsXmlTibcoPull {
            public ItemsXmlTibcoPull() {
                CODICE_PREVENTIVO = "";
                DATA_AUTORIZZAZIONE="";
                NUMERO_ORDINE = "";
                DATA_ORDINE = "";
            }

            public string DATA_ORDINE { get; set; }

            public string NUMERO_ORDINE { get; set; }

            public string DATA_AUTORIZZAZIONE { get; set; }

            public string CODICE_PREVENTIVO { get; set; }
        }

In seconda battuta un parser:

//" NOTA:questo parser prevede in ingresso il path del file xml o il suo contenuto"
public List<ItemsXmlTibcoPull> parser(String path, bool isPath = true){
            List<ItemsXmlTibcoPull> list = new List<ItemsXmlTibcoPull>();
            XElement e =null;
            if (isPath) e = XElement.Load(path);
            else e = XElement.Load(new System.IO.StringReader(path));
//wrappiamo il tag <INFORMAZIONI/>
           foreach (XElement level1Element in e.Elements("INFORMAZIONI"))
            {
                ItemsXmlTibcoPull item = new ItemsXmlTibcoPull();
//e per ogni elemento ne prendiamo il valore      
            foreach (XElement level2Element in level1Element.Elements("CODICE_PREVENTIVO"))
                {
                    item.CODICE_PREVENTIVO = level2Element.Value;
                 
                }
             
                foreach (XElement level2Element in level1Element.Elements("DATA_AUTORIZZAZIONE"))
                {
                    item.DATA_AUTORIZZAZIONE = level2Element.Value;
                 
                }
             
                foreach (XElement level2Element in level1Element.Elements("NUMERO_ORDINE"))
                {
                    item.NUMERO_ORDINE = level2Element.Value;
                  //qualora avessimo dovuto recuperare un attributo sulla property... name ad esempio
                  //result.AppendLine(level1Element.Attribute("name").Value);
                }
                //result.AppendLine(level1Element.Attribute("name").Value);
                foreach (XElement level2Element in level1Element.Elements("DATA_ORDINE"))
                {
                    item.DATA_ORDINE = level2Element.Value;
                   
                }
                list.Add(item);
            }
            return list;
}



ed il gioco è fatto!!!

Non commento ulteriormente perchè si commenta da solo .....

buon lavoro!

ciao


martedì 4 ottobre 2016

Trasformare un foglio Excel in query SQL

Buonasera, è da tanto che non scrivo........

stasera mi sono imbattuto in un foglio excel con soli 70000 record ma molto "sporco", al punto da invalidare il tool Excel To Mysql ( credo si chiami così)


in soldoni ho scritto uno script vba, configurabile, per creare, partendo dal "benedetto" foglio o sheet excel , tutte le query di insert necessare per caricarlo sul "beneamato" DBMS, in questo caso Mysql.





Buon Lavoro :)



PS1: in alto le variabili da configurare,.... i nomi spero siano intuitivi.
PS2: per utilizzarlo, abilitare il tab sviluppo e inserire un pulsante activex,... in posizione 1,1... alla fine dello script capirete perchè
PS3: anche gli interi vengono wrappati dagli apicetti..... miglioratelo :)

ciao


Private Sub CommandButton1_Click()
 
    Dim NOME_TABELLA As String
    NOME_TABELLA = "codifica"
    Dim COLONNAFINALE As Integer
    COLONNAFINALE = 10
    Dim PRIMARIGACONDATI As Long
    PRIMARIGACONDATI = 4
    Dim RIGA_INTESTAZIONI As Integer
    RIGA_INTESTAZIONI = 3
 
    Dim c As Long
    Dim intestazione As String
 
    intestazione = "insert into " & NOME_TABELLA & " ("
    c = 1
 
 
 
 
    While (Cells(RIGA_INTESTAZIONI, c) <> "")
     
        If (intestazione <> "insert into codifica (") And (c < (COLONNAFINALE + 1)) Then
            intestazione = intestazione & ","
        End If
        intestazione = intestazione & CStr(Cells(RIGA_INTESTAZIONI, c))
        c = c + 1
    Wend
    intestazione = intestazione & ") values ("
 
    Dim storei As String
    storei = intestazione
    Dim a As String
    a = "'"
    Dim b As String
    b = ","
 
 
 
    c = PRIMARIGACONDATI
 
    While (Cells(c, 1) <> "")
     
        Dim k As Integer
        k = 1
        Dim query As String
        query = storei
        While (k < (COLONNAFINALE + 1))
         
            If (query <> storei) Then
                query = query & b
            End If
         
            If (Cells(1, k) = "date") Then
                If (Cells(c, k) <> "") Then
                    query = query & a
                    query = query & Mid(Cells(c, k), 7, 4) & "-" & Mid(Cells(c, k), 4, 2) & "-" & Mid(Cells(c, k), 1, 2)
                    query = query & a
                   
                Else
                    query = query & "null"
                End If
           
            Else
                If (Cells(c, k) <> "") Then
                    query = query & a
                    query = query & Replace(CStr(Cells(c, k)), "'", "''")
                    query = query & a
                   
                Else
                    query = query & a & a
                End If
           
           
            End If
         
         
         
         
           
         
             
           
                 
               
            k = k + 1
        Wend
        query = query & ");"
     
        Cells(c, (COLONNAFINALE + 1)) = query
        DoEvents
     
        c = c + 1
     
        'posizione contatore
        Cells(1, 2) = c
    Wend
 
    MsgBox "fine"
 
 
 
End Sub