Autore Topic: come leggo xml con la xmllib??  (Letto 1348 volte)

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
come leggo xml con la xmllib??
« il: 01 Settembre 2011, 15:27:55 »
salve, ho usato la xml lib per salvare il contenuto di una treeview in xml... ma ora come faccio a scorrere gli elementi dell'xml??

ecco il mio xml generato:
Codice: [Seleziona]
<?xml version="1.0" encoding="UTF8"?>
<slyproj>
 <prognam>newproj</prognam>
 <glvar>
  <var type="string">varnam</var>
</glvar>
 <func></func>
 <main>
  <cinput>a</cinput>
  <if cond="(condition) then">
   <cprint>a</cprint>
</if>
</main>
</slyproj>

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: come leggo xml con la xmllib??
« Risposta #1 il: 01 Settembre 2011, 15:32:40 »

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #2 il: 01 Settembre 2011, 18:24:02 »
non mi è d'aiuto! io ho usato la xmllib che c'è su questo forum!

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: come leggo xml con la xmllib??
« Risposta #3 il: 01 Settembre 2011, 18:30:12 »
non mi è d'aiuto! io ho usato la xmllib che c'è su questo forum!

Lo standard XML è lo stesso in tutto il mondo indipendentemente da come lo crei....Come lo scrivi in modo standard, così lo leggi in modo stabdard. Quello che ti ho indicato è uno di questi metodi. Se preferisci altro allora devi aspettare che passi di qui chi ha scritto la libreria in questione.

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #4 il: 02 Settembre 2011, 16:41:06 »
Non ricordo neanche se è la mia...

Comunque, se è quella mia, la classe XmlDocument deve contenere il riferimento al primo elemento (root), dopodiche si passa a prelevare le info sui vari sottoelementi tramite l'array di riferimento (elementi e proprietà xml).

Adesso non sò quale versione hai, perchè nel tempo ne ho fatte svariate, ad ogni modo e se non vado errato dovrebbe esserci anche in allegato un qualche esempio. In caso contrario vedrò di postartelo, ma non ora che sono fuori portata...

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #5 il: 04 Settembre 2011, 11:12:32 »
si md ho usato la tua che c'è in questo forum... c'è solo come generare xml l'esempio

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #6 il: 04 Settembre 2011, 12:40:58 »
Non sò quale versione hai scaricato, comunque è inclusa anche in CLib.

Se dai un'occhiata la codice della classe CXmlDocument, è presente un metodo Print(), che invia in out il contenuto del file xml, opportunamente caricato con il metodo Load().

Leggendo il codice, ne puoi ricavare come la struttura interna viene letta, così da trasferirla anche sui tuoi programmi.

Concettualmente, il Document ha un suo elemento, chiamato root, da cui parte tutta la struttura xml. Tutti gli elementi sono contenuti in un array Elements, e per ogni elemento è presente anche un array di Attribute. Ogni elemento può avere sottoelementi, e quindi ha una proprietà, un array di oggetti, così come anche un array di proprietà, e così via, senza limiti imposti.
Un loop sugli elementi, o sugli attributi, ti permette di leggerne il loro contenuto (Name e Value).

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #7 il: 05 Settembre 2011, 15:57:17 »
Citazione
Un loop sugli elementi, o sugli attributi, ti permette di leggerne il loro contenuto (Name e Value).
   :rolleyes:

facile a dirsi... e a farsi? non mi puoi fare un esempio di come scorro tutti gli elementi del mio xml salvato?

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #8 il: 06 Settembre 2011, 18:32:14 »
Vedere per credere, eh?!?

Comunque, di seguito uno dei pezzi di codice contenuti in pgDesigner2, con cui leggo un file di configurazione. Ovviamente è legato alla struttura del file, per cui prova ad adattarlo alle tue esigenze. Tieni conto che pezzetti di codice simile sono sparsi per i vari e innumerevoli oggetti del mio programma:
Codice: [Seleziona]
STATIC PRIVATE $list AS Object[]
STATIC PUBLIC FUNCTION List() AS Object[]
  DIM oXmlDocument AS pgXmlDocument
  DIM oXmlRoot, oXmlElement AS pgXmlElement
  DIM oXmlAttribute AS pgXmlAttribute
  DIM info AS pgDriverInfo
  IF (IsNull($list)) THEN
    pgApplication.MessageInfo(ME, "Load drivers configuration")
    $list = NEW Object[]
    IF (NOT Exist(DRIVER_FILENAME)) THEN
      Error.Raise(("Not driver list file present !"))
    END IF
    oXmlDocument = pgXmlDocument()
    oXmlDocument.Load(DRIVER_FILENAME)
    oXmlRoot = oXmlDocument.Root.Elements[0]
    FOR EACH oXmlElement IN oXmlRoot.Elements
      info = pgDriverInfo()
      FOR EACH oXmlAttribute IN oXmlElement.Attributes
        SELECT CASE String.Lower(oXmlAttribute.Name)
        CASE "name"
          info.Name = Str(oXmlAttribute.Value)
        CASE "type"
          info.Type = Str(oXmlAttribute.Value)
        CASE "class"
          info.Class = Str(oXmlAttribute.Value)
        CASE "sql"
          info.ImportSqlEnable = (String.Lower(oXmlAttribute.Value) = "true")
        CASE "port"
          info.Port = Str(oXmlAttribute.Value)
        END SELECT
      NEXT
      IF (NOT IsNull(Trim(info.Name)) AND
          NOT IsNull(Trim(info.Class)) AND
          NOT IsNull(Trim(info.Type))) THEN
        IF (pgDatabaseInfo.GetListTypes().Find(info.Type) = -1) THEN
          pgApplication.MessageWarning(ME, ("Database type not valid!") & " [" & info.Type & "]")
        ELSE
          $list.Add(info)
          pgApplication.MessageDebug(ME, "DriverInfo.Add(" & info.ToString() & ")")
        END IF
      END IF
    NEXT
  END IF
  RETURN $list
END
Inoltre, tieni presente che, per esigenze interne al programma, i nomi delle classi potrebbero non essere uguali, ma non credo sia difficile distinguerli...  :D

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #9 il: 06 Settembre 2011, 18:41:20 »
il file lo apro con document.load() ???

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #10 il: 09 Settembre 2011, 11:24:59 »
Leggi il codice nella precedente:

Codice: [Seleziona]
oXmlDocument = pgXmlDocument()
oXmlDocument.Load(DRIVER_FILENAME)

che tradotto in codice più semplice:
Codice: [Seleziona]
DIM oXmlDocument AS NEW XmlDocument
oXmlDocument.Load("nome del file")

Il seguito del codice ti dimostra come poi leggere i dati che la classe ha caricato.

E' necessario che tu interpreti l'esempio, in modo da capire i passi essenziali per usare la classe. Il codice che ti ho postato è un pezzo di codice operativo, che ha dei riferimenti che sono utili ma non interessano direttamente il tuo caso, per cui estrapola la parte interessante per te.

Il metodo "Load" ha solo il compito di leggere e scompattare il contenuto del file. Una volta che ha terminato la sua funzione, i dati scompattati sono contenuti nelle proprietà della classe.

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #11 il: 11 Settembre 2011, 19:31:08 »
Codice: [Seleziona]
Public Sub load_Click()
  Dim $root As Element
  Dim oRoot As Element
  Dim oElement As Element
  Dim oAttribute As Attribute
  Dim oXml As New XmlReader
 
  Dim enam As String
  Dim cp As String
  Dim sv As Integer

  doc = New Document
  Dialog.Title = "Open a Project"
  Dialog.Filter = ["Sly Project (*.slyproj)"]
  If Dialog.OpenFile() Then Return
  SetPath(Dialog.Path)
 
  iab = 4
  tvcode.Clear()
 
  $root = New Element(Null, Null, Null)
  $root.Name = "root"
  $root.Elements.Clear()
  $root.Attributes.Clear()
  oRoot = $root
  oXml.Open($sPath)
  Do Until (oXml.Eof)
    Select Case oXml.Node.Type
    Case XmlReaderNodeType.Element
      'Message.Info(oXml.Node.Name)
     
      Select Case oXml.Node.Name
        Case "glvar"
          tvcode.Add("1", "global variables", vars)
          cp = "1"
        Case "func"
          tvcode.Add("2", "functions", func)
          cp = "2"
        Case "main"
          tvcode.Add("3", "main", main)
          cp = "3"
        Default
          If oXml.Node.Name <> "slyproj" And oXml.Node.Name <> "prognam" Then
            tvcode.Add(iab, oXml.Node.Name, act, cp).EnsureVisible
            tvcode.Item.EnsureVisible
            cp = iab
            iab = iab + 1
          Endif
      End Select
     
      enam = oXml.Node.Name
      oElement = New Element(oRoot, oXml.Node.Name, oXml.Node.Value)
      For Each oXml.Node.Attributes
        oAttribute = New Attribute(oElement, oXml.Node.Name, oXml.Node.Value)
        oElement.Attributes.Add(oAttribute)
      Next
      oRoot.Elements.Add(oElement)
      oRoot = oElement
    Case XmlReaderNodeType.EndElement
      oRoot = oRoot.Parent
      If enam <> "slyproj" And enam <> "prognam" And enam <> "glvar" And enam <> "functions" And enam <> "main" Then
        cp = tvcode.Item.ParentKey
        sv = CInteger(cp) 'ERRORE
        sv = sv - 1
        cp = CString(sv)
      Endif
    Case XmlReaderNodeType.Text
      oElement.Value &= Trim(oXml.Node.Value)
      'Message.Info(oXml.Node.Value)
      If enam <> "slyproj" And enam <> "prognam" Then
        tvcode.Add(CString(iab), enam & " " & oXml.Node.Value, cond, cp).EnsureVisible
        tvcode.Item.EnsureVisible
        iab = iab + 1
      Else If enam = "prognam" Then
        progname = oXml.Node.Value
      Endif
    End Select
    oXml.Read()
  Loop
  oXml.Close()

End

se non mi dasse errore andrebbe! mi dice type mysmatch wanted integer got string  (dove ho fatto il commento errore)

Offline md9327

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.840
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #12 il: 12 Settembre 2011, 13:37:09 »
Ma, hai provato a metterti in debug e analizzare i dati della linea?
Codice: [Seleziona]
sv = CInteger(cp) 'ERRORE
Presumo che la variabile "tvcode" sia una TreeList, per cui prova ad analizzare cosa c'è in questo oggetto.
L'errore non è dipeso direttamente dalla libreria XML, ma è il caso di capire se:
1 - la struttura del file viene letta e decodificata correttamente
2 - i valori che utilizzi sono sempre validi (non null)
3 - la Tree venga popolata correttamente, con tutti i corretti riferimenti (es. la ParentKey)

Offline Raffa50

  • Grande Gambero
  • ***
  • Post: 101
    • Mostra profilo
Re: come leggo xml con la xmllib??
« Risposta #13 il: 12 Settembre 2011, 21:27:39 »
Codice: [Seleziona]
Dim $root As Element
  Dim oRoot As Element
  Dim oElement As Element
  Dim oAttribute As Attribute
  Dim oXml As New XmlReader
 
  Dim enam As String
  Dim cp As Variant
  Dim sv As Variant

  doc = New Document
  Dialog.Title = "Open a Project"
  Dialog.Filter = ["Sly Project (*.slyproj)"]
  If Dialog.OpenFile() Then Return
  SetPath(Dialog.Path)
 
  iab = 4
  tvcode.Clear()
 
  $root = New Element(Null, Null, Null)
  $root.Name = "root"
  $root.Elements.Clear()
  $root.Attributes.Clear()
  oRoot = $root
  oXml.Open($sPath)
 
  Do Until (oXml.Eof)
    Select Case oXml.Node.Type
    Case XmlReaderNodeType.Element
      'Message.Info(oXml.Node.Name)
     
      Select Case oXml.Node.Name
        Case "glvar"
          tvcode.Add("1", "global variables", vars)
          cp = "1"
        Case "func"
          tvcode.Add("2", "functions", func)
          cp = "2"
        Case "main"
          tvcode.Add("3", "main", main)
          cp = "3"
        Default
          If oXml.Node.Name <> "slyproj" And oXml.Node.Name <> "prognam" And oXml.Node.Name <> "cprint" And oXml.Node.Name <> "cinput" Then
            tvcode.Add(iab, oXml.Node.Name, act, cp).EnsureVisible
            tvcode.Item.EnsureVisible
            ablocks[iab] = New Block
            ablocks[iab].tp = oXml.Node.Name
            ablocks[iab].father = True
            cp = iab
            iab = iab + 1
          Endif
      End Select
     
      enam = oXml.Node.Name
      oElement = New Element(oRoot, oXml.Node.Name, oXml.Node.Value)
      For Each oXml.Node.Attributes
        oAttribute = New Attribute(oElement, oXml.Node.Name, oXml.Node.Value)
        oElement.Attributes.Add(oAttribute)
      Next
      oRoot.Elements.Add(oElement)
      oRoot = oElement
    Case XmlReaderNodeType.EndElement
      If (enam = "if" Or enam = "while" Or enam = "else") And iab > 4 Then
        cp = tvcode.Item.ParentKey
        sv = CInteger(cp)
        sv = sv - 1
        cp = CString(sv)
      Endif
      oRoot = oRoot.Parent
    Case XmlReaderNodeType.Text
      oElement.Value &= Trim(oXml.Node.Value)
      'Message.Info(oXml.Node.Value)
      If enam <> "slyproj" And enam <> "prognam" Then
        tvcode.Add(CString(iab), enam & " " & oXml.Node.Value, cond, cp).EnsureVisible
        tvcode.Item.EnsureVisible
        ablocks[iab] = New Block
        ablocks[iab].tp = enam
        ablocks[iab].father = False
        iab = iab + 1
      Else If enam = "prognam" Then
        progname = oXml.Node.Value
      Endif
    End Select
    oXml.Read()
  Loop
  oXml.Close()

si il problema era che la treeview era vuota (null object) ora và (sembra di si testato)