Κυριακή 28 Φεβρουαρίου 2016

Εγχειρίδιο της Μ2000 - Τεύχος 22ο

11.4 Πολλαπλοί δρομείς, σε αρχείο κειμένου.

Μπορούμε να ορίσουμε έναν δρομέα για διάβασμα και έναν για συμπλήρωση. Επειδή μπορούμε να μετακινούμε τους δρομείς έχουμε έναν τρόπο να κάνουμε αυτό που λέμε τυχαία προσπέλαση. Όμως τα αρχεία κειμένου δεν έχουν εγγραφές ομοίου μεγέθους (μήκους). Μπορούμε όμως να διαβάζουμε ή να αλλάζουμε συγκεκριμένα στοιχεία επειδή γνωρίζουμε τι έχουμε βάλει και που. Δείτε εδώ ότι οι δείκτες μαζεύονται σε μια δομή. Αυτό το μάζεμα θα μπορούσαμε να το σώσουμε σε ένα άλλο αρχείο ως αρχείο δεικτών. Είδαμε στο 11.3 ότι μπορούμε να αποθηκεύουμε αριθμούς ως κείμενο και να τους διαβάζουμε ως αριθμούς.
Δεν μπορούμε να χρησιμοποιήσουμε τον τύπο της εξαγωγής γιατί αυτή σβήνει το αρχείο αν υπάρχει και ξεκινάει μετά να το γεμίζει. Να γιατί χρησιμοποιούμε τη συμπλήρωση.

Στατική α$=έναόνομα$
Ομάδα Αλφα {
Ιδιωτικό:
      Πίνακας Α()
      νέο_α
      Τμημα άλλο {
                  Διάβασε Χ, Ζ, ΠουΑκριβώς, Αυτό$
                  Μετάθεση #Χ, .Α(Ζ-1)+(ΠουΑκριβώς-1)*2
                  Τύπωσε #Χ, Αυτό$;
      }
      Τμήμα δικόμου {
                  Διάβασε Χ, Ζ
                  Μετάθεση #Χ, .Α(Ζ-1)
                  Αν όχι κενό τότε {
                        Διάβασε Πόσα
                        Αν όχι κενό τότε {
                              Διάβασε ΠόσαΑκόμα
                              Άλλαξε Πόσα, ΠόσαΑκόμα
                              \\ η μετάθεση δουλεύει με bytes άρα επί 2
                              \\ αφού έχουμε Unicode
                              Μετάθεση #Χ, Μετάθεση(#Χ)+(ΠόσαΑκόμα-1)*2
                        }
                       Βάλε εισαγωγή$(#Χ,Πόσα)
                  } Αλλιώς {
                        Γραμμή Εισαγωγής #Χ, α$
                        Βάλε α$
                  }
            }
Δημόσιο:
      Τμήμα ΒάλεΈνα {
            Διάβασε Χ
            .νέο_α++
            Πίνακας .Α(.νέο_α)
            .Α(.νέο_α-1)=μετάθεση(#Χ)
      }
      Συνάρτηση ΓράψεΠίσω {
            .άλλο
            =0 \\ οκ
      }
      Συνάρτηση ΣτοΣημείο$ {
            \\ οι στατικές έχουν προτεραιότητα
            \\ και είναι κοινές σε κλήσεις συναρτήσεων.
            \\ οπότε τις απομονώνουμε
            .Δικόμου
            =Γράμμα$
      }      
     
}
Άνοιξε α$ για ευρεία εξαγωγή ως κ
      Αλφα.ΒάλεΈνα κ
      Τύπωσε #κ, "Μια γραμμή"
      Αλφα.ΒάλεΈνα κ
      Τύπωσε #κ, "Και άλλη μια γραμμή"
Κλείσε #κ

Αναμονή 100 \\ να είμαστε σίγουροι πως έχει γραφτεί

Άνοιξε α$ για ευρεία Εισαγωγή ως κ
      Άνοιξε α$ για ευρεία Συμπλήρωση ως κ1
            Τύπωσε κ, κ1 \\ έχουμε δυο διαφορετικούς αριθμούς χειρισμού αρχείου
            Κάλεσε Αλφα.ΓράψεΠίσω(κ1, 2, 5, "ΑΛΛΗ")
            Τύπωσε Άλφα.ΣτοΣημείο$(κ,2)
Κλείσε #κ1, #κ


11.5 Αρχεία Πεδίων (τυχαίας προσπέλασης σταθερού μήκους)

Η Μ2000 υποστηρίζει αρχεία τυχαίας προσπέλασης με έναν δρομέα, όπου διαβάζουμε ή γράφουμε μια εγγραφή με ένα μόνο πεδίο. Αυτός ο τρόπος υπάρχει για να δείξει πως παλαιότερα χρησιμοποιούνταν τα αρχεία τυχαίας προσπέλασης. Επειδή έχουμε σταθερό μήκος, δεν είναι αναγκαίο να υπάρχουν αλλαγές παραγράφων. Μάλιστα και εδώ έχουμε την επιλογή ΕΥΡΕΙΑ για unicode ή χωρίς αυτήν για ANSI.
Εδώ η εντολή Μετάθεση και η συνάρτηση Μετάθεση() δεν έχουν εφαρμογή. Κάθε εγγραφή θεωρώ πως είναι μια καρτέλα στοιχείων όπου κάθε στοιχείο έχει μια θέση και ένα πλάτος, και όλα μαζί έχουν ακριβώς το πλάτος εγγραφής. Μπορώ να ξέρω πόσες εγγραφές έχω με τη συνάρτηση Εγγραφές(). 

α$="βασικό_αρχείο1"
Συνάρτηση Υπενθύμιση$ {
      Διάβασε κκ, χχ
      Πάρε #κκ, έναπεδίο$, χχ
      =Μεσ$(έναπεδίο$,31)
      Αν όχι κενό τότε {
         \\ η παρεμβολή για αλφαριθμητικό
         \\ κάνει καταχώρηση αν δώσουμε δεύτερη παράμετρο
         \\ που λέει πόσοι χαρακτήρες θα διαγραφούν
         Παρεμβολή 31,70 έναπεδίο$=πεδίο$(γράμμα$, 70)
         Δώσε #κκ, έναπεδίο$, χχ
      }
}
Άνοιξε α$ για ευρεία πεδία ως κ μήκος=200 \\ μήκος σε bytes άρα 200/2
      Τύπωσε Εγγραφές(κ) \\ 0 την πρώτη φορά και 2 την δεύτερη
      \\ Κάθε εγγραφή είναι μια "καρτέλα", με μικρά πεδία, που γράφονται σε ένα πεδίο!
      Αν Εγγραφές(κ)=0 Τότε {
            Δώσε #κ, πεδίο$("Γιώργος Κ",20)+"6934565612"+Πεδίο$("Οκ",70), 1
            Δώσε #κ, πεδίο$("Πέτρος ",20)+"6963845656"+Πεδίο$("Οφείλει 1000 ευρώ",70), 2
      }
      ΔείξεΕνα(κ,1)
      ΔείξεΕνα(κ,2)
      \\ αλλάζω πεδίο και ξαναδιαβάζω την "καρτέλα"
      παλιό$=Υπενθύμιση$(κ, 2, "Πλήρωσε οκ")
      ΔείξεΕνα(κ,2)
κλείσε #κ

Ρουτίνα ΔείξεΕνα(κκ, χχ)
      Τοπική έναπεδίο$
      Πάρε #κκ, έναπεδίο$, χχ
      Τύπωσε "Όνομα:",Αρισ$(έναπεδίο$,20)
      Τύπωσε "Τηλ:", Μεσ$(έναπεδίο$,21,10)
      Τύπωσε "Υπενθύμηση:"
      Τύπωσε @(5), Μεσ$(έναπεδίο$,31)
Τέλος Ρουτίνας

Για να γράψω νέα "καρτέλα" πρέπει να "Δώσω" σε θέση που δεν υπάρχει καρτέλα. Η συνάρτηση Εγγραφές() μου δίνει τον αριθμό εγγραφών άρα αν δώσω την εγγραφή σε αυτόν τον αριθμό συν ένα, τότε θα γράψω μια νέα καρτέλα.

Το ερώτημα εδώ είναι πώς σβήνω καρτέλες; Η απάντηση είναι απλή και κατανοητή: Αν θέλουμε να σβήσουμε, τότε έχουμε ένα μικρό πεδίο του ενός χαρακτήρα (μέσα στο ένα πεδίο της εγγραφής) το οποίο έχει το νόημα "είμαι καρτέλα για διαγραφή". Κάποια στιγμή μπορούμε να αναπαράγουμε το αρχείο χωρίς να συμπεριλάβουμε αυτές τις καρτέλες, ή να τις χρησιμοποιήσουμε (ανακύκλωση). Το καλύτερο είναι η συντήρηση, δηλαδή η διαγραφή σε νεκρό χρόνο, ώστε να μην υπάρχει περίπτωση το διαγραμμένο να χρησιμοποιηθεί ταυτόχρονα από άλλους χρήστες.
Μια ιδέα για τη νέα καρτέλα είναι να βάλει πρώτα ένα τυχαίο αλλά γνωστό περιεχόμενο, και να δει μετά ότι είναι αυτό μέσα, αν δεν είναι τότε επαναλαμβάνει την εισαγωγή (δεν θα είναι αν προλάβει άλλο πρόγραμμα και γράψει εκείνο που θεωρούσαμε τελευταίο, αφού πρώτα το γράψουμε και πριν το διαβάσουμε για να το επιβεβαιώσουμε).


Για να βάλω αριθμό σε πεδίο έχω μερικούς τρόπους:
α$=μορφή$("[{0:3:10}]",12.12121)
Τύπωσε α$
α$=μορφή$("[{0:3:-20}]",1224.12121)
Τύπωσε α$
α$=μορφή$("{0}[{1:3:10}]","χ=",12.12121)
Τύπωσε α$
α$=μορφή$("{0}[{1:3:-20}]","ζ=",1224.12121)
Τύπωσε α$

Η συνάρτηση μορφή$() επιστρέφει ένα αλφαριθμητικό. Δέχεται τουλάχιστον ένα αλφαριθμητικό. Μπορεί να δεχτεί στην συνέχεια μια λίστα τιμών ως μια σειρά όπου κάθε τιμή θα είναι  αλφαριθμητικό ή αριθμός (μπορούμε να δώσουμε παραστάσεις π.χ. 12+3), Στο πρώτο αλφαριθμητικό (και αυτό μπορεί να είναι αλφαριθμητική παράσταση) έχουμε την δυνατότητα να δώσουμε στοιχεία για το που θα μπουν τα στοιχεία της λίστας. Το πρώτο στοιχείο έχει τον αριθμό 0, έτσι ένα {0} σημαίνει βάλε την τιμή του πρώτου στοιχείου. Μπορούμε να το βάλουμε σε περισσότερες από μία  θέσεις, και μάλιστα μπορεί στο ενδιάμεσο να βάλουμε το {1} ώστε να μπει η δεύτερη τιμή. Βλέπουμε στο παράδειγμα ότι υπάρχει ο χαρακτήρας ":" και μάλιστα δυο φορές δίπλα από τον αριθμό στοιχείου (όταν σε μια τιμή ορίζεται διακριτή θέση, με κάποιο νόημα, τότε λέγεται στοιχείο, π.χ. ένας αριθμός 5 στο σκορ ενός παιχνιδιού δεν είναι απλά μια τιμή 5 αλλά το σκορ με τιμή 5 άρα είναι στοιχείο, τιμή με νόημα). Πράγματι αυτό συμβαίνει γιατί έχουμε δυο  δυνατές παραμέτρους, τον αριθμό δεκαδικών (στρογγυλοποίησης, αλλά συμπληρώνει μηδενικά αν χρειαστεί), και το εύρος του πεδίου (αυτό μας ενδιαφέρει στο θέμα μας). Το εύρος πεδίου δίνεται σε χαρακτήρες και αν είναι αρνητικό σημαίνει δεξιά στοίχιση, ενώ θετικό αριστερή.

11.6 Αρχεία XML με χρήση Msxml2.DOM

Στα αρχεία πεδίων, αλλά και στα αρχεία κειμένου όπου γράφουμε κάτι παραπάνω από κείμενο, αν οι θέσεις παίζουν ρόλο τότε λέμε ότι έχουμε αρχεία με στοιχεία, που θα γίνουν δεδομένα για κάποια άλλη διεργασία ή για εμφάνιση.

“Δεδομένα είναι τα στοιχεία που δίνονται σε μια διεργασία, και τα στοιχεία είναι τιμές με νόημα. Η διεργασία τροφοδοτεί τα δεδομένα ως τιμές σε παραμέτρους συναρτήσεων, και οι παράμετροι δίνουν τιμές μέσω αριθμητικών ή άλλων παραστάσεων σε μεταβλητές/πίνακες που συγκεντρώνουν την πληροφορία. Η πληροφορία είναι δηλαδή το αποτέλεσμα επεξεργασίας δεδομένων, και ακριβώς αυτό είναι το αντικείμενο της πληροφορικής. Να γιατί το αρχείο, και ο τρόπος χειρισμού έχει μεγάλη σημασία στη πληροφορική. Tα λειτουργικά συστήματα λέγονταν DOS disk operating system γιατί κύρια δουλειά τους ήταν να υποστηρίζουν αρχεία σε δίσκο, σε αποθηκευτικό μέσο”

Πρέπει να κατανοήσουμε ότι δεν είναι όλα τα αρχεία "περιγραφικά" με την έννοια ότι αν ανοίξουμε το αρχείο να μπορούμε να καταλάβουμε το περιεχόμενό του. Αυτό συμβαίνει όπου δεν υπάρχει σήμανση τιμών με ονομασίες ώστε να προκύπτουν με απλή ανάγνωση τα στοιχεία. Στα αρχεία που είδαμε δεν υπάρχει σχήμα θέσεων, έναν χάρτη που να  δηλώνει  τι τιμή είναι η κάθε τιμή σε κάθε θέση του αρχείου. Το πρόγραμμα που γράφει το αρχείο και πιθανόν ένα διαφορετικό πρόγραμμα που το διαβάζει, γνωρίζουν τι και πώς να πάρουν από αυτό. Αυτό σημαίνει ότι το νόημα έχει περαστεί στο κώδικα, στο πρόγραμμα. Υπάρχουν τύποι αρχείων όπου οι τιμές περιγράφονται  σε επίπεδο εγγραφής μέσα στο αρχείο. Τέτοια αρχεία είναι τα XML ή αρχεία μιας γλώσσας σήμανσης όπως αναφέρει το wiki.

Στη Μ2000 θα χρησιμοποιήσουμε ένα αντικείμενο που δίνει η Microsoft. Εκτός από αντικείμενα που σχηματίζουν οι ομάδες, έχουμε και έναν δεύτερο τύπο αντικειμένων, που δεν μπαίνουν σε ομάδες. (δεν μπορούμε να αντιγράψουμε τέτοιο αντικείμενο, αλλά μπορούμε να το περάσουμε με αναφορά). Θα χρησιμοποιήσουμε ένα αντικείμενο COM το οποίο δεν είναι γραμμένο σε M2000, δεν αποτελεί δε κάποια εξωτερική βιβλιοθήκη ρουτινών αλλά όταν το συνδέουμε στην εφαρμογή (λέγεται καθυστερημένη σύνδεση, διότι δεν έχει γίνει με την εκκίνηση της εφαρμογής αλλά μετά από παραγγελία)
από την έκδοση 8.9 αναθεώρηση 2 μπορούμε να φορτώνουμε χωρίς το BOM και με το δείκτη -2 λέμε να σώνει κείμενο σε UTF-8 χωρίς BOM. Στην ανάγνωση το βρίσκει η Φόρτωσε.Έγγραφο και το βάζει στο έγγραφο, ώστε στο σώσιμο να διατηρήσει την έλλειψη του BOM (κάποια bytes, που δηλώνουν στην αρχή του κειμένου το τύπο αρχείο κειμένου).

Προστέθηκε στο παράδειγμα και ο τρόπος που διατρέχουμε όμοια στοιχεία και διαβάζουμε ένα στοιχείο από αυτά. Χρησιμοποιήθηκαν ονόματα μεταβλητών από το παράδειγμα εδώ:
https://msdn.microsoft.com/en-us/library/ms757073(v=vs.85).aspx

Τα Όρισε αντικείμενο Τίποτα εδώ είναι πλεονασμός γιατί στο πέρας εκτέλεσης θα διαγραφούν τα αντικείμενα. Επίσης στην Για ορίζουμε πάνω σε αντικείμενα άλλα αντικείμενα, αλλά εδώ δεν μας πειράζει, γιατί έχουμε στην ουσία δείκτη σε αντικείμενο και τα παλιά αυτόματα διαγράφονται (ή για να είμαστε εδώ πιο ακριβείς, ουσιαστικά τα αντικείμενα είναι μέσα στο ΑντικείμενοXml, και κάθε φορά δημιουργούμε μια "συντόμευση" σε αυτό που ζητάμε, άρα στην ουσία η "συντόμευση" διαγράφεται όχι το πραγματικό αντικείμενο, το οποίο θα διαγραφεί όταν διαγραφεί το
ΑντικείμενοXml).


Έγγραφο α$={<?xml version="1.0"?>
<Ονόματα>
      <στοιχείο αα="69">
      <όνομακωδ>VB6</όνομακωδ>
      <ποσότητα>2</ποσότητα>
      </στοιχείο>
      <στοιχείο αα="70">
      <όνομακωδ>C++</όνομακωδ>
      <ποσότητα>3</ποσότητα>
      </στοιχείο>
</Ονόματα>
}
Σώσε.Έγγραφο α$,"άλφα.xml", -2
Αναμονή 100
Όρισε ΑντικείμενοXml "Msxml2.DOMDocument.6.0"
Μέθοδος ΑντικείμενοXml, "Load", κατ$+"άλφα.xml" ως οκ
Αν οκ τότε {
      Όρισε ΣτοιχείοXML με ΑντικείμενοXml, "documentElement"
      Μέθοδος ΣτοιχείοXML, "selectSingleNode", "στοιχείο[@αα=70]" ως ΕπιλεγμένοΣτοιχείο
      Μέθοδος ΕπιλεγμένοΣτοιχείο, "selectSingleNode", "όνομακωδ" ως ΕπιλεγμένοΠεδίο
      \\ αυτή η Με είναι διαφορετική από την Με στην δομή Επίλεξε Με
      \\ εδώ έχουμε εντολή ενώ εκεί είναι στοιχείο της δομής
      Με ΕπιλεγμένοΠεδίο, "text" ως η_τιμή_μου$
      Τύπωσε η_τιμή_μου$
      \\ Μπορώ να αλλάξω τιμή
      η_τιμή_μου$="George"
      \\ Και μπορώ να σώσω
      Μέθοδος ΑντικείμενοXml, "Save", κατ$+"alfa.xml" ως ok
     Μέθοδος ΣτοιχείοXML, "getElementsByTagName", "στοιχείο" ως objNodeList
     Με objNodeList , "length" ως objNodeList.length
     Τύπωσε objNodeList.length
     Για ι=0 έως objNodeList.length-1 {
           Μέθοδος objNodeList , "item", ι ως objNodeList.item
            Μέθοδος objNodeList.item, "getElementsByTagName", "όνομακωδ" ως objNodeList2
            Μέθοδος objNodeList2 , "item", 0 ως objNodeList.item2
           'Με  objNodeList.item2 , "xml" ως α12$
           Με objNodeList.item2 , "text" ως α12$
           Pen 12 {
                 Τύπωσε α12$
           }
           Όρισε objNodeList.item2 Τίποτα
           Όρισε objNodeList2 Τίποτα
           Όρισε objNodeList.item Τίποτα
     }
      Όρισε objNodeList Τίποτα
      Όρισε ΕπιλεγμένοΠεδίο Τίποτα
      Όρισε ΕπιλεγμένοΣτοιχείο Τίποτα
      Όρισε ΣτοιχείοXML Τίποτα
}
Όρισε ΑντικείμενοXml Τίποτα
Εγγραφο ααα$
Φόρτωσε.Έγγραφο ααα$, "alfa.xml"
Αναφορά ααα$



Επεξήγηση (απλοποιημένη όσο γίνεται):
Τα αντικείμενα τύπου COM Component Object Model είναι μια τεχνολογία που δίνει αντικείμενα σε εκτελέσιμη μορφή για να χρησιμοποιηθούν από άλλες διεργασίες, όπως εδώ από τη Μ2000, ενώ υπάρχει σύστημα αδειών, ώστε τα αντικείμενα να μπορούν να χρησιμοποιηθούν μόνο από αυτή την εφαρμογή που έχει άδεια να το κάνει. Με αυτό τον τρόπο γράφτηκε κλειστός κώδικας, ιδιοταγής/ιδιόκτητος, με σκοπό το κέρδος, δηλαδή να πουλιέται σε όποιον τον έχει ανάγκη. Το λειτουργικό σύστημα Windows ενσωματώνει αυτή την τεχνολογία (έρχεται από το 1994) και μάλιστα την επεκτείνει, αλλά εδώ δεν θα μας απασχολήσει αυτό.

Αυτό που έχει σημασία για το εγχειρίδιο είναι ότι τα αντικείμενα ορίζονται σε ένα όνομα βάσει μιας ταυτότητας-περιγραφής: "Msxml2.DOMDocument.6.0", και όταν δεν τα χρειαζόμαστε πρέπει να ορίσουμε στο όνομα που συνδέεται με το αντικείμενο να πάρει το Τίποτα. Και να το ξεχάσουμε η Μ2000 θα το κάνει για μας, αλλά είναι καλή πρακτική να το κάνουμε με μια δήλωσε Όρισε όνομακάτι Τίποτα

Ορίζουμε αντικείμενα ως αποτέλεσμα μεθόδων (εδώ συνάρτηση/μέθοδος είναι ένα πράγμα), Τα ονόματα των μεθόδων είναι στα αγγλικά. Για παράδειγμα η μέθοδος "selectSingleNode" αναφέρεται εδώ  στο XML DOM METHODS. Βλέπουμε ότι έχουν βάλει παραδείγματα σε jscript και C/C++.  Ο σκοπός των αντικειμένων COM (ή DOM ως σχετική ορολογία) είναι να μπορούμε να ενώσουμε κώδικα με αντικείμενο έτοιμο για εκτέλεση.

Η εντολή Όρισε χρησιμοποιείται και για εξωτερικές βιβλιοθήκες με σύνδεση συνάρτησης σε ρουτίνα της βιβλιοθήκης (απλή αναφορά γίνεται εδώ θα το δούμε σε επόμενο τεύχος):

Ορισε ΠροσθεσεΠλαγιαΓραμμη Απο "Shlwapi.PathAddBackslashW" { &Μονοπατι$ }
ένα_μονοπάτι$ = "C:"+Επαν$(Χαρ$(0), 250)
Κάλεσε Κενή ΠροσθεσεΠλαγιαΓραμμη(&ένα_μονοπάτι$)
Σημ 1 : Α=ΠροσθεσεΠλαγιαΓραμμη(&ένα_μονοπάτι$)
Τύπωσε ΑριστερόΜέρος$(ένα_μονοπάτι$,Χαρ$(0))



Στο κύριο πρόγραμμα (για το xml) συνδέουμε μια μεταβλητή με την ιδιότητα ενός αντικειμένου:
Με ΕπιλεγμένοΠεδίο, "text" ως η_τιμή_μου$
Αν δώσουμε την παρακάτω εντολή για να δούμε τους τύπους των μεταβλητών:
Τύπωσε τύπος$(η_τιμή_μου$), τύπος$(ΕπιλεγμένοΠεδίο)
PropReference  IXMLDOMElement
Θα πάρουμε τα ονόματα των αντικειμένων. Το η_τιμή_μου$ δεν είναι απλά μια αλφαριθμητική μεταβλητή αλλά ένα αντικείμενο που δίνει τιμή αλφαριθμητική και δέχεται επίσης τιμή αλφαριθμητική, την οποία προωθεί στο αντικείμενο τύπου IXMLDOMElement που λέμε εδώ ΕπιλεγμένοΠεδίο και ειδικότερα στην ιδιότητα text.

Πρέπει να κάνουμε μια νέα σειρά ορισμών (για τα ίδια ονόματα) βάζοντας άλλες παραμέτρους στη κλήση της πρώτης μεθόδου, ώστε να πάρουμε το στοιχείο με αα=69 χωρίς να χρειαστεί άλλη φορά να συνδέσουμε την η_τιμή_μου$ με το ιδιότητα text (και να το κάνουμε πάλι δεν υπάρχει πρόβλημα). Οι αναφορές σε αυτά τα αντικείμενα μπορούν να αλλαχτούν, και κάποιο αντικείμενο μείνει χωρίς αναφορά (τις μετράει εσωτερικά) τότε διαγράφεται αυτόματα (να γιατί δηλώνουμε Τίποτα, όταν θέλουμε να σβήσουμε ένα αντικείμενο). Οι εντολές Όρισε,  Μέθοδος και Με δεν δέχονται στατικές μεταβλητές.

      Μέθοδος ΣτοιχείοXML, "selectSingleNode", "στοιχείο[@αα=69]" ως ΕπιλεγμένοΣτοιχείο
      Μέθοδος ΕπιλεγμένοΣτοιχείο, "selectSingleNode", "όνομακωδ" ως ΕπιλεγμένοΠεδίο
      Τύπωσε η_τιμή_μου$
      


Μια τελευταία επισήμανση. Δείτε στο πρόγραμμα ότι φορτώνουμε το xml αρχείο, το χειριζόμαστε, σβήνοντας ή αλλάζοντας κάποια στοιχεία, όμως οι αλλαγές δεν έχουν γίνει στο αρχείο. Για να γίνουν πρέπει να το σώσουμε. Αυτό σημαίνει ότι το αρχείο αυτό δεν μπορεί να λειτουργήσει μέσω του αντικειμένου ταυτόχρονα για πολλά προγράμματα. Για εργασίες όπου τα αρχεία μπορούν να αλλαχθούν ταυτόχρονα από πολλούς χρήστες έχουμε τις βάσεις δεδομένων. Τις οποίες θα δούμε σε άλλο τεύχος (Η Μ2000 χειρίζεται βάσεις δεδομένων και SQL ερωτήματα).



Στο αρχείο Info υπάρχουν τα XML και XML2 προγράμματα. Εδώ είναι το XML2. Στην έκδοση 10 υπάρχει το αντικείμενο xmldata και μπορούμε να διαχειριστούμε XML βάσεις μέσα στη μνήμη, να σώσουμε ή φορτώσουμε από το αρχείο στο αντικείμενο, να κάνουμε αναζήτηση,
Το xmldata είναι ένα COM αντικείμενο που περιέχεται στο διερμηνευτή. Δείτε διάφορες γραμμές με τη With. Αυτή η εντολή είτε στέλνει δεδομένα σε ιδιότητες, είτε διαβάζει από ιδιότητες σε μεταβλητές, είτε συνδέει ιδιότητες με ονόματα που μετά απευθείας διαβάζουν ή γράφουν χωρίς τη χρηση With (ή Με στα ελληνικά - το Με χρησιμοποιείται και στην Επίλεξε, αλλά ο διερμηνευτής τα ξεχωρίζει)


pen 14
Cls 5,0
Print $(4),
declare databank xmldata
with databank, "xml" as doc$, "beautify" as beautify, "status" as status$
doc$={<?xml?>
<table id="1">
<schema><schema:fields row="element">2</schema:fields>
<schema:fieldname type="s">Country</schema:fieldname>
<schema:fieldname  type="s">Continent</schema:fieldname>
</schema><element><Country   >Greece</Country><Continent>Europe</Continent>
</element><element><Country>Germany</Country><Continent>Europe</Continent>
</element><element><Country>Australia</Country><Continent>Australia</Continent>
</element><element><Country>India</Country><Continent>Asia</Continent>
</element>
</table>
}


beautify=-4
Report 3, doc$
With Databank, "Attr" as Attr$()
Print status$
Print


// Show structure
fieldnames=list
rowlist=list
Method databank, "GetListByTag", "schema:fields", 1 as Result
If len(Result)=1 then
    Stack Result {Read fieldsNo}
    With fieldsNo, "Text" as No$, "Attr" as fieldsno.tag$()
    elementname$=fieldsno.tag$("row")
    Print "There are two fields: "; val(No$)
    Print "Each row has this name: ";elementname$
    Print "Scanning the schema:fieldname"
    Method databank, "GetListByTag", "schema:fieldname" as Result
    declare m xmldata
    oldvalue=m
    with m, "text" as m.value$, "attr" as m.attr$()
    k=each(Result)
    while k
        m=stackitem(k)
        Print k^+1,m.value$, "Type: ";m.attr$("type")
        append fieldnames, m.value$:=m.attr$("type")
    end while
       Print "Press a key"; : Push Key$ : Drop: Print
    // now we have the fields in a list, where key is the name of field, and value is the type
    pen 11 {Print "Scanning the fieldnames list, produced from previous scanning"}
    z=each(fieldnames)
    while z
        Print z^+1, eval$(z!), eval$(z)
    end while
    pen 11 {Print "Scanning all rows with tag: ";elementname$}
    Method databank, "GetListByTag", elementname$ as Result
    Print "Found ";Len(Result);" records or rows"
    With m, "textFromChild" as child.value$(), "xml" as m.doc$
    k=each(Result)
    z=each(fieldnames)
    while z
        pen 13 {Print eval$(z!),}
    end while
    Print
    while k
        m=stackitem(k)
        z=each(fieldnames)
        while z
            if z^=0 then append rowlist, child.value$(eval$(z!)):=m
            if eval$(z)="s" then Print child.value$(eval$(z!)),
        end while
        Print
    end while
    Print "Scanning sorted rows  (descening on country) from rowlist, prepared before"
        sort descending rowlist
        swap m, oldvalue
        k=each(rowlist)
        while k
            m=eval(rowlist)
            z=each(fieldnames)
            while z
                if eval$(z)="s" then Print child.value$(eval$(z!)),
            end while
            Print
        end while
end if


with databank, "lastchild" as last, "firstchild" as first, "nextchild" as nextchild
pen 15 {Print "The xml not alter the children - yet"}
pen 13 {
    beautify=-4
    Report 3, doc$
}


pen 11 {
    Report "Now we rearrange the children. We remove all children and add them, the schema and the the elements from the list.  We handle the pointers, the object's pointers. So when we remove all childrens the actual xmlData (children) kept by pointers in other places."
}
Print
Method databank, "GetListByTag", "schema", 1 as schema_stack
Method databank, "RemoveChildren"
stack schema_stack {Read the_schema}
Method databank, "AppendChildObj", the_schema
k=each(rowlist)
while k
    m=eval(rowlist)
    Method databank, "AppendChildObj", m
End While
beautify=-4
Report 3, doc$


with databank, "lastchild" as last, "firstchild" as first, "nextchild" as nextchild
pen 11 {
    Report "Now we remove specific childs, we remove 2 childs from third, we start from first child, then we move two times to nextchild and perform two times RemoveChild method. Also we can change the value of id Attribute of table"
}
Attr$("id")="2"
Print "New attribute value for id:";Attr$("id")


dd=first
//with dd, "xml" as dd.text$
dd=nextchild
dd=nextchild
method databank, "RemoveChild"
method databank, "RemoveChild"
beautify=-4
Report 3, doc$
Print status$






Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.