Κατανεμημένες Εφαρμογές και Ηλεκτρονικό Εμπόριο -> XML

5 Προσεγγίσεις στην επεξεργασία XML

5.1 SAX

Ένα από τα προβλήματα των σαρωτών XML είναι οτι δεν έχουν γίνει προσπάθειες τυποποίησης. Υπάρχει ένας αριθμός σαρωτών που έχουν υλοποιηθεί με διαφορετικούς τρόπους και με διαφορετικά σύνολα μεθόδοων. Για να ξεπεράσουμε αυτό το πρόβλημα έχει αναπτυχθέι ένα API που καλεί έναν σαρωτή και στη συνέχεια επεξεργάζεται μια εσωτερική μορφή του πηγαίου κώδικα XML που έχει χτίσει το API. Ένα τέτοιο API γνωστό ως SAX (Simple API for XML) αντλεί τη προέλευσή του από μια ταχυδρομική λίστα για την XML. Ο προγραμματιστής Peter Murray-Rust που ανάπτυξε τον XML περιηγητή JUMBO έστειλε ένα μήνυμα που δήλωνε οτι είχε βαρεθεί να συντηρεί τρείς εκδόσεις του JUMBO για τρείς διαφορετικούς σαρωτές. Αυτό οδήγησε στη συνεργασία αρκετών προγραμματσιτών στη δημιουργία του API.

Το SAX API περιέχει μια σειρά μεθόδους όμοιες με αυτές του Aelfred

Το SAX είναι ένα παράδειγμα επεξεργασίας συμβάντων: η ιδέα πίσω από το SAX είναι οτι οι γραμμές μιας γλώσσας ορισμένης με κάποιο XML DTD υφίστανται ακολουθιακή επεξεργασία και κάθε φορά που συναντάται ένα εναρκτήριο επίθεμα, εκτελέιται μια μέθοδος που σχετίζεται με αυτό το συμβάν.

Ένα παράδειγμα κώδικα SAX φαίνεται παρακάτω. Το SAX επεξεργάζεται το DTD που ακολουθεί:

  <?xml version = "1.0" standalone = "yes'?>
<!DOCTYPE BOOKLIST [
<!ELEMENT BOOKLIST (BOOK)*>
<!ELEMENT BOOK (TITLE, AUTHORS, PRICE, PUBLISHER)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT AUTHORS (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>
<!ELEMENT PUBLISHER (#PCDATA)>
<!ATTLIST PRICE
AMOUNTCURRENCY CDATA #REQUIRED
DISCOUNT CDATA "0">
]>

 
Το DTD δίνει προδιαγραφές για περιγαρφή βιβλίων. Κάθε βιβλίο ορίζεται από τον τίτλο, τους συαγγραφείς, την τιμή και τον εκδότη. Κάθε μια από αυτές τις οντότητες ορίζεται από ένα αλφαριθμητικό. Η τιμή σχετίζεται με μια ιδιότητα, που ορίζει το νόμισμα, το δε αλφαριθμητικό της τιμής πρέπει να είναι ακέραιος αριθμός. Επίσης κάθε τιμή σχετίζεται με προαιρετική έκπτωση. Αν δεν υπάρχει έκπτωση, η προκαθορισμένη τιμή της είναι μηδέν.

Ακολουθεί ένα τεκμήριο XML που βασίζεται στο συγκεκριμένο DTD.

  <BOOKLIST>
<BOOK>
<TITLE>The Endless Path</TITLE>
<AUTHORS>Jones</AUTHORS>
<PRICE AMOUNTCURRENCY = "Pounds">200</PRICE>
<PUBLISHER>Pearson</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>My Story</TITLE>
<AUTHORS>Roberts</AUTHORS>
<PRICE AMOUNTCURRENCY = "SW Francs">500</PRICE>
<PUBLISHER>McMillan</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>XML for Beginners</TITLE>
<AUTHORS>Ince</AUTHORS>
<PRICE AMOUNTCURRENCY = "Dollarss" DISCOUNT = "5">300</PRICE>
<PUBLISHER>Pearson</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>Java and Nirvana</TITLE>
<AUTHORS>Rowlands</AUTHORS>
<PRICE AMOUNTCURRENCY = "Pounds">400</PRICE>
<PUBLISHER>Wiley</PUBLISHER>
</BOOK>
</BOOKLIST>

Ακολουθεί ένα πρόγραμμα για την επεξεργασία του XML τεκμηρίου.

  //Imports for parser and SAX API
import org.apache.xerces.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class BookValues extends DefaultHandler
{
public static void main(String[] args)
{
BookValues b = new BookValues("catalogue.txt");
}

public BookValues(String file)
{
try
{
//Sets uo a parser
xParser.setContentHandler(this);
try
{
xParser.parse(file);
}
catch(Exception e)
{
System.out.println("Problem");
}
}
 catch(Exception e)
{
System.out.println("Problem starting XML parser "
+ e.getMessage());
}
}

public void error(SAXParseException se)
{
//Executed when a serious error occurs
//in processing the XML source
System.out.println("Error: Problem with XML "
+ se.getMessage());
}

public void warning(SAXParseException se)
{
//Executed when a minor problem occurs
//in processing the XML source
System.out.println("Warning: Problem with XML "
+ se.getMessage());
}

public void startDocument() throws SAXException
{
//Executed when the XML document is started
System.out.println("Document started");
}

public void startElement (String elementName,
Attributes al) throws SAXException
{
//Executed when a start element is encountered
String attributeName, attributeValue;
System.out.println("Start ELEMENT = " + elementName);
if (al.getLength() > 0)
{
//The element has some attributes
System.out.println("Attributes are ");
for (int j=0; j<al.Length();j++)
{
//List the attributes, the method getLocalName
//returns the name and getValus returns the value
attributeName = al.getLocalName(j);
attributeValue = al.getValue(j);
System.out.println("Attribute name is + attributeName
+ " Attribute value is " + attributeValue);
}
}
}

public void endElement(String elementName)
throws SAXException
{
//Executed when an end element is encountered
System.out.println("End ELEMENT = " + elementName);
}


public void endDocument() throws SAXException
{
//Executed when the XML document is finished
System.out.println("Document finished");
}

public void characters(char[] chars, int start, int length)
throws SAXException
{
//Executed when a string is encountered
System.out.println("String read is " + new
String(chars, start, length));
}
}

Ο κώδικας αποτελείται από διάφορες μεθόδους. Οι μέθοδοι startDocument κια endDocument εκτελούνται στην αρχή και στο τέλος της σάρωσης του XML τεκμηρίου. Επίσης π[εριλαμβάνονται δύο μέθοδοι -warning και error- που εκτελούνται να εμφανιστούν μέγάλα ή μικρά προβλήματα στη σάρωση.

Οι υπόλοιπες μέθοδοι πυροδοτούνται με την εμφάνιση των αντίστοιχων συμβάντων. Για παράδειγμα ο κώδικας

public void endElement(String elementName)
throws SAXException
{
//Executed when an end element is encountered
System.out.println("End ELEMENT = " + elementName);
}

εκτελείται όταν εμφανιστεί ένα ληκτικό επίθεμα. Μέσα στη μέθόδο startElement που εκτελείται όταν εμφανίζεται ένα εναρκτήριο επίθεμα υπάρχει ο κώδικας

  if (al.getLength() > 0)
{
//The element has some attributes
System.out.println("Attributes are ");
for (int j=0; j<al.Length();j++)
{
//List the attributes, the method getLocalName
//returns the name and getValus returns the value
attributeName = al.getLocalName(j);
attributeValue = al.getValue(j);
System.out.println("Attribute name is + attributeName
+ " Attribute value is " + attributeValue);
}
}

Αυτός ελέγχει πρώτα αν υπάρχουν ιδιότητες για το συγκεκριμένο στοιχείο. Αν όντως υπάρχουν τότε εκτελείται ο βρόχος for j που εμφανίζει τα ονόματα και τις τιμές των ιδιοτήτων.

Ο κατασκευαστής περιέχει κώδικα που ενεργοποιεί τον σαρωτή και ξεκινά τη διεργασία ανάγνωσης των γραμμών του τεκμηρίου XML. Το αρχείου που περιέχει το κείμενο του τεκμηρίου περνάει στον σαρωτή σαν όρισμα.

Το αποτέλεσμα που εμφανίζει η εκτέλεση του κώδικα για το συγκεκριμένο αρχείο XML φαίνεται παρακάτω:

  Document started
Start ELEMENT = BOOKLIST
Start ELEMENT = BOOK
Start ELEMENT = TITLE
String read is The Endless Path
End Element = TITLE
Start ELEMENT = AUTHORS
String read is Jones
End ELEMENT = AUTHORS
Start ELEMENT = PRICE
Attributes are
Attribute name is AMOUNTCURRENCY Attribute value is Pounds
Attribute name is DISCOUNT Attribute value is 0
String read is 200
End ELEMENT = PRICE
Start ELEMENT = PUBLISHER
Stringread is Pearson
End ELEMENT = PUBLISHER
End ELEMENT = BOOK
Start ELEMENT = BOOK
Start ELEMENT = TITLE
String read is My Story
End Element = TITLE
Start ELEMENT = AUTHORS
String read is Roberts
End ELEMENT = AUTHORS
Start ELEMENT = PRICE
Attributes are
Attribute name is AMOUNTCURRENCY Attribute value is PoundsSW Francs
Attribute name is DISCOUNT Attribute value is 0
String read is 500
End ELEMENT = PRICE
Start ELEMENT = PUBLISHER
Stringread is McMillan
End ELEMENT = PUBLISHER
End ELEMENT = BOOK
Start ELEMENT = BOOK
Start ELEMENT = TITLE
String read is XML for Beginners
End Element = TITLE
Start ELEMENT = AUTHORS
String read is Ince
End ELEMENT = AUTHORS
Start ELEMENT = PRICE
Attributes are
Attribute name is AMOUNTCURRENCY Attribute value is Dollars
Attribute name is DISCOUNT Attribute value is 5
String read is 300
End ELEMENT = PRICE
Start ELEMENT = PUBLISHER
Stringread is Pearson
End ELEMENT = PUBLISHER
End ELEMENT = BOOK
Start ELEMENT = BOOK
Start ELEMENT = TITLE
String read is Java and Nirvana
End Element = TITLE
Start ELEMENT = AUTHORS
String read is Rowlands
End ELEMENT = AUTHORS
Start ELEMENT = PRICE
Attributes are
Attribute name is AMOUNTCURRENCY Attribute value is Pounds
Attribute name is DISCOUNT Attribute value is 0
String read is 400
End ELEMENT = PRICE
Start ELEMENT = PUBLISHER
Stringread is Wiley
End ELEMENT = PUBLISHER
End ELEMENT = BOOK
End ELEMENT = BOOKLIST
Document finished
End ELEMENT

  

5.2 DOM

Το μοντέλο DOM απαιτεί την αποθήκευση στη μνήμη του κειμένου XML που με την επεξεργασία θα ματεσχηματιστεί σε δένδρο.  Σε αυτό διαφέρει από την προσέγγιση του SAX όπου τιο κείμενο δεν αποθηκεύεται στη μνήμη αλλά υφίσταται ακολουθιακή επεξεργασία από αρχείο.

Παρακάτω δίνεται ένα πρόγραμμα Java βασισμένο στο DOM που επεξεράζεται το ίδιο αρχείο XML που περιγραψαμε στη προηγούμενη ενότητα. 
  import org.w3c.dom.*;
import org.ibm.xml.parser.Parser;

public class DOMParser
{
public static void displayXML(Node nd)
{
short nodeVal = nd.getNodeType();

if (nd.DOCUMENT_NODE==nodeVal)
{
//This is a document node, apply displayXML again
displayXML(((Document)nd).getDocumnetElement());
}

if (nd.ELEMENT_NODE==nodeVal)
{
//This is an element node, get the name of node
String nodeName = nd.getNodeName();
System.out.println("Name of Node = " + nodeName);
//Get the attributes
NamedNodeMap nm = nd.getAttriutes();
if (nm != null)
{
//There are some attributes, display them
for (int k=0;k<nm.getLength();k++)
{
//Iterate over getLangth attributes
Node currAttribute = nm.item(k);
//Get the name of the attribute
String attributeName =
currAttribute.getNodeName();
//Get the value of the attribute
String attributeValue =
currAttribute.getNodeValue();
System.out.println(
"Attribute name = " + attributeName +
"Attribute value = " + attributeValue);
}  
}

//Get all the child nodes
NodeList nl = nd.getChildNodes();
//If there are any child nodes iterate over them
//executing displayXML again
if (nl != null)
{
for (int j=0;j<nl.getLength();j++)
displayXML(nl.item(j));
}
}

if (nd.TEXT_NODE==nodeVal)
{
//Text encoutered
if(!nd.getNodeValue().equals("\n"))
System.out.println(nd.getNodeValue());
}
}

public static void main(String[] args)
{
try
{
//Set up and sart the parser
String file = "catalogue.txt";
InputStream inStream = new FileInputStream(file);
Parser dp = new Parser(file);
Document doc = dp.readStream(inStream);
//Execute displayXML to display the XML source
displayXML(doc);
System.out.println("There were " +
dp.getNumberOfErrors() + " Errors");
}
catch (Exception E)
{
System.out.println ("Problem with XML processor " +e);
}
}
}

    To DOM εργάζεται διατρέχοντας τους κόμβους ενός δένδρου του τεκμηρίου, παρόμοιο με αυτό του Σχήματος 8.4. Ένας κόμβος μπορεί να είναι διαφόρων τύπων και η δομή tου κώδικα που επεξργάζεται το κείμενο XML θα περιέχει μια μεγάλη συλλογή δηλώσεων if που θα ανακαλυπτουν τον τύπο του κάθε κόμβου και την επεξεργασία που πρέπει να υποστεί.

Η μέθοδος displayXML εκτελεί την βασική επεξεργασία του δένδρου, με τη πρώτη δήλωση να ανακαλεί τον κόμβο προς επεγργασία.

  short nodeVal = nd.getNodeType();

Η μέθοδος getNodeType επιστρέφει μια σταθερά τύπου short που καθορίζει τον τύπο του κόμβου. Ο κώδικας που απομένει εξετάζει τον κόμβο και εκτελεί την κατάλληλη επεξεργασία ανάλογα με τον τύπο του κόμβου. Πρώτα γίνεται έλεγχος αν πρόκειται για κόμβο τεκμηρίου

  if (nd.DOCUMENT_NODE==nodeVal)
{
//This is a document node, apply displayXML again
displayXML(((Document)nd).getDocumnetElement());
}

Αυτός είναι κόμβος της μορφής

<!DOCTYPE BOOKLIST SYSTEM "books.txt">

που είναι η κεφαλίδα του κειμένου XML και ορίζει οτι πρόκειται για τεκμήριο του τύπου BOOKLIST και το αρχείο των βιβλίων του BOOKLIST είναι το books.txt. Η σταθερά nd.DOCUMENT_NODE έχει την τιμή που ορίζει οτι πρέκειται για κόμβο τεκμηρίου.

Στη συνέχεια ο κώδικας καλεί ξανά τη μέθοδο displayXML θέτει ώς αρχικό όρισμα τη ρίζα του δένδρου, δηλαδή τον κόμβο τεκμηρίου, και στη συνέχεια διατρέχει τους κόβους - παιδιά.

Η επόμενη δήλωση if εξετάζει αν ο τρέχων κόμβος είναι στοιχείο, για παράδειγμα το <BOOK>
  if (nd.ELEMENT_NODE==nodeVal)
Πρώτα ο κώδικας βρίσκει το όνομα του κόμβου και το εμφανίζει, για παράδειγμα BOOK ή PUBLISHER. Στη συνέχεια βρίσκει τις ιδιότητες του στοιχείο και τις τοποθετεί στο αντικείμενο     NameNodeMap..
  //This is an element node, get the name of node
String nodeName = nd.getNodeName();
System.out.println("Name of Node = " + nodeName);
//Get the attributes
NamedNodeMap nm = nd.getAttriutes();
Το επόμενο τμήμα κώδικα
  if (nm != null)
{
//There are some attributes, display them
for (int k=0;k<nm.getLength();k++)
{
//Iterate over getLangth attributes
Node currAttribute = nm.item(k);
//Get the name of the attribute
String attributeName =
currAttribute.getNodeName();
//Get the value of the attribute
String attributeValue =
currAttribute.getNodeValue();
System.out.println(
"Attribute name = " + attributeName +
"Attribute value = " + attributeValue);
}  
}
πρώτα ελέγχει αν υπάρχουν ιδιότητες, για παράδειγμα AMOUNTCURRENCY. Στη συνέχεια προαπελαύνει όλες τις ιδιότητες στο nm. Κάθε ιδιότητα τοποθετείται σε μια μεταβλητή Node και στη συνέχεια εξάγονται το όνομα και η τιμή της μέσω των μεθόδων getNodeName και getNodeValue, για παράδειγμα AMOUNTCURRENCY και pounds. Τα αποτελέσματα εμφανίζοναι.

Το επόμενο τμήμα κώδικα παραλαμβάνει όλους τους κόμους που είναι παιδιά του τρέχοντος κόμβου, τους τοποθετεί σε μια λίστα NodeList nl και τους διατρπέχει εφαρμόζοντας την displayXML. Πρόκειται για αναδρομή.
  //Get all the child nodes
NodeList nl = nd.getChildNodes();
//If there are any child nodes iterate over them
//executing displayXML again
if (nl != null)
{
for (int j=0;j<nl.getLength();j++)
displayXML(nl.item(j));
}
Η μέθοδος item εξάγει τους κόμβους από τη λίστα και στη συνέχεια εφαρμόζεται η displayXML.

Ο τελικός τύπος κόμβου είιναι αυτός του απλού κείμενου όπως  για παράδειγμα  το κείμενο Roberts
  <AUTHORS>Roberts</AUTHORS>
Ο κώδικας  είναι
  if (nd.TEXT_NODE==nodeVal)
{
//Text encoutered
if(!nd.getNodeValue().equals("\n"))
System.out.println(nd.getNodeValue());
}
Σε περίπτωση που το κείμενο είναι απλά αλλαγή γραμμής τότε αυτό δεν εμφανίζεται. Το τελικό τμήμα του κώδικα εγκαθιστά τη διαδικασία σάρωσης.
  public static void main(String[] args)
{
try
{
//Set up and sart the parser
String file = "catalogue.txt";
InputStream inStream = new FileInputStream(file);
Parser dp = new Parser(file);
Document doc = dp.readStream(inStream);
//Execute displayXML to display the XML source
displayXML(doc);
System.out.println("There were " +
dp.getNumberOfErrors() + " Errors");
}
catch (Exception E)
{
System.out.println ("Problem with XML processor " +e);
}
}
Το αρχείο catalogue.txt  συνδέεται με ένα αντικείμενο inStream το οποίο χρησιμοποιείται ως είσοδος στον σαρωτή, που παράγει ως έξοδο το αντικείμενο doc το οποίο περνά ως είσοδος στη μέθοδο displayXML.

Η εκτέλεση παράγει το ακόλουθο αποτέλεσμα:
  Name of Node = BOOKLIST
Name of Node = BOOK
Name of Node = TITLE
The Endless Path
Name of Node = AUTHORS
Jones
Name of Node = PRICE
Attributes are
Attribute name = AMOUNTCURRENCY Attribute value = Pounds
Attribute name = DISCOUNT Attribute value = 0
200
Name of Node = PUBLISHER
Pearson
Name of Node = BOOK
Name of Node = TITLE
My Story
Name of Node = AUTHORS
Roberts
Name of Node = PRICE
Attributes are
Attribute name = AMOUNTCURRENCY Attribute value = SW Fancs
Attribute name = DISCOUNT Attribute value = 0
500
Name of Node = PUBLISHER
McMillan
Name of Node = BOOK
Name of Node = TITLE
XML for Beginners
Name of Node = AUTHORS
Ince
Name of Node = PRICE
Attributes are
Attribute name = AMOUNTCURRENCY Attribute value = Dollars
Attribute name = DISCOUNT Attribute value = 5
300
Name of Node = PUBLISHER
Pearson
Name of Node = BOOK
Name of Node = TITLE
Java and Nirvana
Name of Node = AUTHORS
Rowlands
Name of Node = PRICE
Attributes are
Attribute name = AMOUNTCURRENCY Attribute value = Pounds
Attribute name = DISCOUNT Attribute value = 0
400
Name of Node = PUBLISHER
Wiley

There were 0 Errors  

Αυτό είναι το DOM. Αν γράφετε προγράμματα Java που προσπελέυνουν αρχεία XML θα έχετε να επιλέξετε το API που θα χρησιμοποιήσετε: είτε μια προσέγγιση βασισμένη σε συμβάντα όπως το SAX, είτε μια προσέγγιση επεξεργασίας δένδρου όπως  το DOM. Υπάχρουν μερικά σημεία που πρέπει να έχουμε στο μυαλό μας όταν κάνουμε αυτή την επιλογή:
Στις δύο τεέυταίες ενότηες περιέγραψα δύο προσεγγίσεις επεξεργασίας XML βασισμένες στη Java. Υπάρχει ακόμη μια δημοφιλής προσέγγιση βασιμένη σε μια έννοια γνωστή ως XSL.

5.3 XSL

5.3.1 Εισαγωγή
H XSL (eXtensible Style Language) είναι μια γλώσσα που βασίζεται στην XML και χρησιμοποιείται στον τύπο επεξεργασίας που συζητήθηκε στις δύο προηγούμενες ενότητες. Συχνά η γλώσσα αναφέρεται και ως XSLT και αναπτύθχθηκε από το W3 Consortium. Πριν εξετάσουμε λεπτομερώς πώς δουλεύει η XSLT είναι ανάγκαίο να εισάγουμε την ένοια του χώρου ονομάτων (namespace).

Ένας χώρος ονομάτων είναι ένας τρόπος να συνθέτουμε νέους ορισμούς XML από υπάρχοντες ορσιμούς. Ας υποθέσουμε οτι θλελουμε να ορίσουμε ένα χρήστη σε XML και να επαναχρησιμοποιήσουμε αυτό τον ορισμό σε διαφορετικές περιπτώσεις. Για παράδειγμα ας υποθέσουμε οτι έχουμε το DTD ενός χρήστη υπολογιστικού συστήματος αποθηκευμένο στη θέση www.open.ac.uk/users/Ince/Departments. Ας υποθέσουμε οτι υπάρχουν τέσσερα στοιχεία, τα EMPLOYEELIST, USER, NAME, EMAILADDRESS ορισμένα από τα ζέυγη επιθεμάτων <EMPLOYEELIST></EMPLOYEELIST>, <USER></USER>, <NAME></NAME> και <EMAILADDRESS></EMAILADDRESS>. Αυτά τα επιθέματα μπορούν να χρησιμοποιηθούν σε ένα κείμενο XML. Ακολουθεί ένα παράδειγμα

  <DEPARTMENT:EMPLOYEELIST XMLNS:DEPARTMENT=
"http://www.open.ac.uk/users/Ince/Departments">
<DEPARTMENT:USER>
<DEPARTMENT:NAME>
Darrel Ince
</DEPARTMENT:NAME>
<DEPARTMENT:EMAILADDRESS>
D.C.Ince@computing.ac.uk
</DEPARTMENT:EMAILADDRESS>
</DEPARTMENT:USER>
<DEPARTMENT:USER>
<DEPARTMENT:NAME>
Walter Evans
  </DEPARTMENT:NAME>
<DEPARTMENT:EMAILADDRESS>
W.Evans@computing.ac.uk
</DEPARTMENT:EMAILADDRESS>
</DEPARTMENT:USER>
<DEPARTMENT:USER>
<DEPARTMENT:NAME>
Robert Wilson
</DEPARTMENT:NAME>
<DEPARTMENT:EMAILADDRESS>
R.S.Wilson@computing.ac.uk
</DEPARTMENT:EMAILADDRESS>
</DEPARTMENT:USER>
</DEPARTMENT:EMPLOYEELIST>

Η ιδιότητα XMLNS καθορίζει οτι ο παραπάνω κώδικας XML ορίζει ένα τοπικό χώρο ονομάτων. Αυτό σημαίνει οτι όλα τα επιθέματα και οι ιδιότητες στο κείμενο πρέπει να έχουν ώς πρόθεμα το όνομα του χώρου ονομάτων (DEPARTMENT). Η ιδιότητα XMLNS επίσης ορίζει τη θέση όπου βρίσκεται ο κώδικας. Ο κώδικας αυτός ορίζει ένα τοπικό χώρο ονομάτων.

Τώρα, μπορεί να σκεφτείτε οτι πρόκειται για μια άχρηστη περιπλοκή, αν το μόνο που κάνουμε είναι να χρησιμοποιούμε επιθέματα από το συγκεκριμένο χώρο ονομάτων. Όμως, η δόμηση των DTDs με αυτό τον τρόπο επιτρέπει τη χρήση επιθεμάτων και ιδιοτήτων από άλλους χώρους ονομάτων. Για παράδειγμα, ας υποθέσουμε οτι εχουμε ένα χώρο ονομάτων που ορίζει το στοιχείο JOBTITLE και κρατείται στη θέση www.open.ac.uk/users/Ince/UserDetails. Ο κώδικας XML που ακολουθεί δείχνει πως αυτή η πληροφορία μπορεί να εισαχθεί στο υπάρχον XML κείμενο.
  <DEPARTMENT:EMPLOYEELIST XMLNS:DEPARTMENT=
"http://www.open.ac.uk/users/Ince/Departments"
XMLNS:USERDETAILS=
"http://www.open.ac.uk/users/Ince/UserDetails">
<DEPARTMENT:USER>
<DEPARTMENT:NAME>
Darrel Ince
</DEPARTMENT:NAME>
<USERDETAILS:JOBTITLE>
Programmer
</USERDETAILS:JOBTITLE>
<DEPARTMENT:EMAILADDRESS>
D.C.Ince@computing.ac.uk
</DEPARTMENT:EMAILADDRESS>
</DEPARTMENT:USER>
<DEPARTMENT:USER>
<DEPARTMENT:NAME>
Walter Evans
  </DEPARTMENT:NAME>
<USERDETAILS:JOBTITLE>
Project manager
</USERDETAILS:JOBTITLE>
<DEPARTMENT:EMAILADDRESS>
W.Evans@computing.ac.uk
</DEPARTMENT:EMAILADDRESS>
</DEPARTMENT:USER>
<DEPARTMENT:USER>
<DEPARTMENT:NAME>
Robert Wilson
</DEPARTMENT:NAME>
<USERDETAILS:JOBTITLE>
Project assistant
</USERDETAILS:JOBTITLE>
<DEPARTMENT:EMAILADDRESS>
R.S.Wilson@computing.ac.uk
</DEPARTMENT:EMAILADDRESS>
</DEPARTMENT:USER>
</DEPARTMENT:EMPLOYEELIST>
Οι γραμμές ήταν
  XMLNS:USERDETAILS=
"http://www.open.ac.uk/users/Ince/UserDetails"
εισάγουν έναν απομακρυσμένο χώρο ονομάτων που τα στοιχεία του μπορούν να χρησιμοποιηθούν τοπικά. Όμως τα στχοιεία πρέπει να έχουν ως πρόθεμα το όνομα του απομακρθσμένου χώρου ονομάτων, όπως στο
  <USERDETAILS:JOBTITLE>
Programmer
</USERDETAILS:JOBTITLE>
Η προέλευση του χώρου ονομάτων

Οι χώροι ονομάτων αρχικά αναπτύχθηκαν από το W3 Consortium εξ' αιτίας της μεγάλης δημοφιλίας της XML. Πολλοί χρήστες άρχισαν να ορίζουν τα δικά τους XML DTDs και ήθελαν να χρησιμοποιήσουν αυτά τα DTDs σε άλλες εφαρμογές. Δυστυχώς όμως, μερικά DTDs είχαν τα ίδια ονόματα στοιχείων με άλλα. Οι χώροι ονομάτων ε΄δωσαν τη λύση. Είναι ένα μηχανισμός για την επίλυση της συνωνυμίας αλλά και την απομακρυσμένη χρήση DTDs.

Αν η ιδιότητα XMLNS χρησιμοποιείται μόνο τοπικά δεν υπάρχει λόγος να έχουμε πρόθεμα στα στοιχεία του κειμένου XML. Για παράδειγμα ο παραπάνω κώδικας μπορεί να γραφεί

  <DEPARTMENT:EMPLOYEELIST XMLNS=
"http://www.open.ac.uk/users/Ince/Departments"
XMLNS:USERDETAILS=
"http://www.open.ac.uk/users/Ince/UserDetails">
<USER>
<NAME>
Darrel Ince
</NAME>
<USERDETAILS:JOBTITLE>
Programmer
</USERDETAILS:JOBTITLE>
<EMAILADDRESS>
D.C.Ince@computing.ac.uk
</EMAILADDRESS>
</USER>
<USER>
<NAME>
Walter Evans
  </NAME>
<USERDETAILS:JOBTITLE>
Project manager
</USERDETAILS:JOBTITLE>
<EMAILADDRESS>
W.Evans@computing.ac.uk
</EMAILADDRESS>
</USER>
<USER>
<NAME>
Robert Wilson
</NAME>
<USERDETAILS:JOBTITLE>
Project assistant
</USERDETAILS:JOBTITLE>
<EMAILADDRESS>
R.S.Wilson@computing.ac.uk
</EMAILADDRESS>
</USER>
</EMPLOYEELIST>

5.3.2 Επεξεργασία κειμένου XML με χρήση XSL
H XSL είναι ένας τύπος πρωτόγονης γλώσσας προγραμματισμού εκφρασμένης με όρους επιθεμάτων XML. Αυτό μπορεί να εξηγηθέι καλύτερα με ένα παράδειγμα. Το παράδειγμα αφορά σε μια απλή βάση δεδομένων με λεπτομέρειες βιβλίων που μπορεί να κρατά ένας ερευνητής σε ένα αρχείο υπολογιστή.

Ακολουθεί ένα παράδειγμα του κειμένου ενός τέτοιου αρχείου
  <?xml version = "1.0"?>
<?xml-stylesheet type = "text/xml"
href = "example.xsl"?>

<BOOKLIST>
<BOOK>
<TITLE>
An introduction to the saxophone
</TITLE>
<AUTHORS>
E.J. Wilson and R.Vitra
</AUTHORS>
<COMMENT>
Good introductory stuff but ignores recent
 history post 1995
</COMMENT>
</BOOK>
<BOOK>
<TITLE>
The Selmer Factory
</TITLE>
<AUTHORS>
R. Logier
</AUTHORS>
<COMMENT>
The definitive work on the Selmer Factory,a
bit light on early saxophone production
</COMMENT>
</BOOK>
<BOOK>
<TITLE>
New Orleans, Jazz and the rise of Saxophone
</TITLE>
<AUTHORS>
D. Brindeck
</AUTHORS>
<COMMENT>
A popular treatment
</COMMENT>
</BOOK>
Ακολουθεί ένα φύλλο στυλ που παράγει ένα τεκμήριο HTML ππό το παραπάνω κέιμενο.
  <?xml version = "1.0"?>
<?xsx:stylesheet version = "1.0" xmlns:xsl = "..">
<xsl:template match = "BOOKLIST">
<HTML>
<HEAD>
<TITLE>
Generated HTML for the book
</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match = "BOOK">
<P>
<xsl:value-f select = "TITLE"/>
</P>
</xsl:template>
<xsl:stylesheet>
Οι πρώτες δύο γραμμές
  <?xml version = "1.0"?>
<?xsx:stylesheet version = "1.0" xmlns:xsl = "..">
ορίζουν την χρησιμοποιούμενη έκδοση της XML και τη τοποθεσία του προτύπου φύλλου στύλ που εφαρμόζεται. Ανάμεσα στα διπλά εισαγωγικά μπορεί να βρίσκεται το κατάλληλο URL του W3 Consortium, ή μια άλλη δεύθυνση στο ενός ιστοτόπου, ή η διαδρομή καταλόγου ενός τοπικού αντιγράφου. Παρατηρείστε οτι η δεύτερη γραμμή ορίζει ένα χώρο ονομάτων, πράγμα που σημαίνει οτι όλα τα επιθέματα και οι ιδιότητες που σχετίζονται με αυτό το χώρο ονομάτων θα πρέπει να έχουν ως πρόθεμα το xsl.

Οι επόμενες γραμμές 
  <xsl:template match = "BOOKLIST">
<HTML>
<HEAD>
<TITLE>
Generated HTML for the book
</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
καθορίζουν τις ενέργειες που εκτελούνται όταν συναντάται το επίθεμα BOOKLIST. Η επεξεργασία ορίζει οτι αρχικά παράγονται τα στοιχεία καφαλίδας ενός τεκμηρίου HTML, στη συνέχεια εφραμόζονται τα υπόλοιπα τμήματα του κώδικα, αν υπάρχει σχετική ταύτιση επιθεμάτων στο κείμενο XML, και στο τέλος παράγονται τα τελικά  στοιχεία ενός τεκμηρίου HTML. Παρατηρείστε οτι η γραμμή
  <xsl:apply-templates/>
είναι συντομογραφία της πλήρους έκφρασης
  <xsl:apply-templates>
</xsl:apply-templates>
και επιτρέπεται όταν δεν υπάρχει κείμενο μεταξύ των επιθεμάτων. Το επόμενο τμήμα είναι το
  <xsl:template match = "BOOK">
<P>
<xsl:value-f select = "TITLE"/>
</P>
</xsl:template>
Αυτό το τμήμα ορίζει τον μετασχηματισμό που εκτελείται όταν συναντάται το επίθεμα  BOOK. Αρχικά παράγεται ένα εναρκτήριο επίθεμα παραγράφου, στη συνέχεια το κείμενο που σχετίζεται με το επίθεμα TITLE, και στο τέλος ένα ληκτικό επίθεμα παραγράφου.

Το αποτέλεσμα της επεξεργασίας θα είναι η παραγωγή του παρακάτω τεκμηρίου HTML
  <HTML>
<HEAD>
<TITLE>
Generated HTML for the book
</TITLE>
</HEAD>
<BODY>
<P>
An introduction to the saxophone
</P>
<P>
The Selmer Factory
</P>
<P>
New Orleans, Jazz and the rise of Saxophone
</P>
</BODY>
</HTML>
Ο παρακάτω κώδικας δείχνει πώς μπορούμε να χειριστούμε τα υπόλοιπα στοιχεία της XML. Κάθε ένα από τα στοιχεία TITLE, ELEMENT, COMMENT μετασηματίζεται σε κατάλληλο κείμενο και διαχωρίζεται με ένα στοιχείο <BR>.
  <?xml version = "1.0"?>
<?xsx:stylesheet version = "1.0" xmlns:xsl = "..">
<xsl:template match = "BOOKLIST">
<HTML>
<HEAD>
<TITLE>
Generated HTML for the book
</TITLE>
</HEAD>
<BODY>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match = "BOOK">
<P>
<xsl:value-f select = "TITLE"/>
</P>
</xsl:template>
<xsl:template match = "BOOK/AUTHORS">
<BR>
<xsl:value-f select = "."/>
<BR>
</xsl:template>
<xsl:template match = "BOOK/COMMENT">
<BR>
<xsl:value-f select = "."/>
<BR>
</xsl:template> 
<xsl:stylesheet>
Εδώ ορίζονται τρείς ταυτίσεις. Επειδή στην ουσία είναι ίδιες αρκεί να επικεντρωθούμε σε μία.
  <xsl:template match = "BOOK/COMMENT">
<BR>
<xsl:value-f select = "."/>
<BR>
</xsl:template>
¨Έχουμε ταύτιση με το στοιχείο COMMENT που είναι ένθετι στο στοιχείο BOOK. Όααν αυτή η ταύτιση συμβεί τότε παράγεται η τρέχουσα τιμή του στοιχείου (αυτό δηλώνει η τελεία) και περικλείεται από το επίθεμα <BR> της HTML.

Το φύλλο στυλ μετά την επεξργασία θα καταλήξει στο παρακάτω κώδικα HTML
  <HTML>
<HEAD>
<TITLE>
Generated HTML for the book
</TITLE>
</HEAD>
<BODY>
<P>
An introduction to the saxophone
<BR>
E.J. Wilson and R. Vitre
<BR>
<BR>
Good introductory stuff but ignores recent history
post 1995
<BR>
</P>
...
</BODY>
</HTML>
Αυτή η ενότητα αποτελεί μια σύντομη εισαγωγή στην XSL. Εν τούτοις περιγράφει τις κύριες έννοιες που υποστηρίζουν αυτή τη τεχνολογία. Η XSL είναι μια πολύ μεγάλη τεχνολογία με εργαλεία ανάλογα με αυτά που βρίσκουμε στις τυπικές διαδικαστικές γλώσσες προγραμματισμού, όπως οι δηλώσεις απόφασης και επανάληψης.

Η XSL μπορεί να εφαρμοστεί με διάφορους τρόπους:

5.4 Μορφοποίητικά αντικείμενα

Μέχρι τώρα σε αυτή την ενότητα επικεντρωθήκαμε στην επίδειξη απλών μετασχηματισμών από κέιμενο XML σε HTML. Αν και αυτός είναι  σημαντικός μετασχηματισμός, συχνά απαιτούνται άλλοι πιο περίπλοκοι, για παράδειγμα μετασχηματισμοί σε εκτυπώσιμες μορφές.

Για την υποστήριξη τέτοιων μετασχηματισμών το W3 Consortium έχει ορίσει μορφοποιητικά αντικείμενα που υποστηρίζουν διάφορες ιδιότητες εκτύπωσης όπως τύπους γραμματοσειρών και μέγεθος γραμμάτων.

Παρακάτω φαίνεται ένα παράδειγμα μπρφοποιητικού αντικειμένου που χησιμοποιείται για να ορίσει κάποια λειτουργία εκτύπωσης

  <fo:block font-family = "sans-serif"
font-weight = "bold"
font-size = "36pt"
font-height = "48pt">
..
</fo:block>

Εδώ το κείμενο που περικλείεται από αυτό το μπλοκ ορίζεται να εμφανιστεί έντονο, με μέγεθος γραμματος 36 στιγμών, σε γραμματοσειρά sans-serif και με ύψος γραμμής 48 στιγμών.

Για να χρησιμοποιήσετε μορφοποιητικά αντικείμενα εισάγετε εντολές μορφοποίησης όπως η παραπάνω στον κώδικα XSL και στη συνέχεια εφαρμόζετε έναν επεξεργαστή γνωστό ως FOP που παρέχεται από το W3 Cosnortium και μπορεί να μετατρέψει το κείμενο σε μορφή PDF (Portable Document Format) που αναγνωρίζεται από τον πολύ δημοφιλή, και δωρεάν διαθέσιμο, Adobe Acrobat Reader.

Τα μορφοποιητικά αντικείμενα περιέχουν όλα τα εργαλεία που θα  περιμένατε από ένα σύνθετο εκτυπωτικό πακέτο, όπως:
Συνήθως χρησιμοποιούνται σε συνδυασμό με την XSL, με τον επεξεργαστή XSL να αναφέρεται στις οδηγίες μορφοποίησης, κατά την επεξεργασία κάποιου κειμένου βασιμένου σε XML.

5.5 Συστήματα εκδόσεων Ιστού

Ένα σύστημα εκδόσεων Ιστού, συχνά αποκαλούμενο και πλαίσιο εκδόσεων Ιστού, είναι λογισμικό που συνήθως υλοποιείται ως ένα σύνολο από APIs που επιπτρέπουν την διαχείριση μεγάλου όγκου τεκμηρίων XML.

Για παράδειγμα, ένα σύστημα εκδόσεων Ιστού επιτρέπει στο προσωπικό που είναι υπέυθυνο για τη διαχείριση μιας μεγάλης συλλογής τεκμηρίων να μεταβάλλει το κείμενο ενός τεκμηρίου που βασίζεται σε XML και να το επανεκδόσει με ποικίλους τρόπους, για παράδειγμα να το μεταφορτώσει και να το εκτυπώσει σε μια εκτυπωτική μονάδα ή να το συμεπριλάβει σε ένα ιστοχώρο. Όλη αυτή η διαδικασία είναι όσο το δυνατό πιό αυτοματοποιημένη. Για παράδειγμα, θεωρείστε οτι ο χρήστης ενός συστήματος εκδόσεων Ιστού είναι μια εταιρία ανάπτυξης λογισμικού που διατηρεί τα βασικά της κείμενα με αυστηρή τυποποίηση, έτσι ώστε -ας πούμε- οι προδιαγραφές απαιτήσεων να διατηρούνται έτσι ώστε κάθε απαίτηση να εισάγεται σε ξεχωροστή παράγραφο σε μια λίστα απαιτήσεων. Όταν χρεαιστεί να γίνει μια αλλαγή σε ένα τέτοιο σύνολο κειμένων, πρέπει να εκτελεστούν τα  παρακάτω ενέργειες:


Ο αριθμός των συστημάτων εκδόσεων Ιστού είναι μικρός. Πιθανότατα το πιό γνωστό είναι το Cocoon που είναι τμήμα του έργου Apache. To Cocoon είναι ένα έργο Ανοικτού Λογισμικού που βασίζεται σε Java serlets. Το μόνο που κάνειο χρήστης για να το λειττουργήσει είναι να εισάγει ένα URL που αναφέρεται στο τεκμήριο που θέλει να παράγει σε μορφή HTML ή PDF.