Share |

domenica 30 maggio 2010

XPath: Utilizzo delle Funzioni

Il linguaggio XPath, utile per navigare un documento XML, fornisce un ampio set di funzioni per potenziare l'estrazione dei dati XML, rendendo questa fase più flessibile e precisa.

Le funzioni XPath sono raggruppate in tre categorie:

  • Node-Set: accettano un node-set come argomento e restituiscono node-set o informazioni su un particolare nodo di esso;
  • String: eseguono valutazioni, formattazioni e manipolazioni su stringhe;
  • Boolean: valutano l'espressione passata come argomento e restituiscono un risultato booleano true o false, vero o falso;
  • Number: valutano l'espressione passata come argomento e restituiscono un risultato numerico;

Tutte le funzioni hanno questa sintassi:
nomeFunzione( [ espressione ] ).

Come si nota, l'espressione può essere facoltativa.

Gli esempi che seguono le spiegazioni sono stati creati utilizzando il documento XML serra.xml

Funzioni della categoria Node-Set

Funzioni Node-Set
FunzioneDescrizioneEsempioRisultato
count(espressione)Restituisce il conteggio dei nodi individuati dall'espressionecount(//pianta)4
position()Restituisce la posizione del nodo corrente relativamente alla lista di nodi in cui si trova.
last()Restituisce il numero di posizione dell'ultimo nodo di una lista//pianta[last()]4
name()Se usato nella forma name(node-set) restituisce il nome del nodo passato come argomento, se invece è utilizzato semplicemente nella forma name() restituisce il nome del nodo corrente
local-name()Resituisce il nome locale di un nodo senza il prefisso di namespace. L'utilizzo è identico a name().
namespace-uri()Restituisce l'URI del namespace di un nodo. L'utilizzo è identico a name().

Funzioni della categoria String












Funzioni String
FunzioneDescrizioneEsempioRisultato
concat()Concatena due o più stringhe passate come argomenticoncat('rosa', 'canina')rosacanina
contains()Determina se la prima stringa passata come parametro contiene la seconda stringa, passata anch'essa come parametro. Se i parametri passati sono dei riferimenti a nodi, di essi viene preso il valore ed interpretato come stringacontains('tulipano','pan')true
normalize-space()Elimina gli spazi spazi bianchi in eccesso da una stringa o dal valore di un nodo interpretato come stringanormalize-space(' rosa canina ')rosa canina
starts-with()Valuta se la stringa passata come primo argomento inizia con la stringa passata come secondo argomento. Restituisce true o falsestarts-with('tulipano','pan')false
string()Converte un oggetto in una stringastring(count(//pianta))"4"
string-length()Restituisce il numero di caratteri presenti nella stringa passata come parametro.string-length('felce')5
substring()Restituisce la sotto-stringa presente nella stringa passata come primo parametro ricavandola partendo dalla posizione passata come secondo argomento per una lunghezza pari al valore del terzo parametro.substring('soqquadro',4,6)quadro
substring-after()Restituisce la sotto-stringa presente nella stringa passata come primo parametro successiva alla stringa passata come secondo parametro.substring('tips.tricks@gmail.com','@')gmail.com
substring-before()Restituisce la sotto-stringa presente nella stringa passata come primo parametro precedente alla stringa passata come secondo parametro.substring('tips.tricks@gmail.com','@');tips.tricks
translate()Restituisce la stringa passata come primo parametro sostituendo i caratteri passati come secondo parametro con quelli contenuti nel terzo parametro.translate('mirko','m','M')Mirko

Funzioni della categoria Boolean

Funzioni Boolean
FunzioneDescrizioneEsempioRisultato
boolean()Converte l'espressione passata come parametro in un valore booleano. Se l'argomento è un numero, la funzione restituirà true nel caso il parametro fosse diverso da zero, altrimenti false. Se l'argomento è una stringa, la funzione restituirà true se questa non è vuota, altrimenti false. Se l'argomento è un riferimento ad un node-set, la funzione restituirà true se questo non è vuoto, altrimenti false.boolean(//serra)true
not()Restituisce true se l'argomento è una affermazione falsa, e viceversanot(contains('tulipano','pan'))false
false() e true()Restituiscono sempre false e true
lang()Restituisce true o false a seconda che l'attributo xml:lang del nodo corrente corrisponda a quello passato alla funzione come parametro.lang('it')true/false

E' da notare che la sintassi_XPath supporta le funzioni su numeri anche se utilizzate con gli operatori_XPath di confronto nelle espressioni filtro.

Funzioni della categoria Number

Funzioni Number
FunzioneDescrizioneEsempioRisultato
number()Converte l'argomento passato alla funzione in numero, se non è possibile convertire restituisce NaN (not a number).number('22342.3456'), number('rosa')22342.3456, NaN
ceiling()Arrotonda un numero decimale all'intero superiore.ceiling(0.5)1
floor()Arrotonda un numero decimale all'intero inferiore.floor(0.5)0
round()Arrotonda un numero decimale all'intero superiore o inferiore più prossimo.round(0.6), round(0.5), round(0.4)1, 1, 0
sum()Converte i valori del node-set passato come argomento in numeri e restituisce la loro somma.sum(//pianta/@prezzo)Restituisce la somma di tutti gli attributi prezzo dei nodi <pianta>

Come da premessa, la tecnologia XPath fornisce un ricco toolset per la selezione dei dati XML e l'elaborazione di condizioni e nodi contenuti in un documento XML: essa infatti è ampiamente utilizzata nei parsers come sistema di ricerca dei nodi.

Alla prossima, MA.

venerdì 28 maggio 2010

XPath: Operatori e Selezioni

Il linguaggio di selezione XPath, utile per filtrare i dati presenti in files XML, offre un'ampia lista di operatori per poter eseguire selezioni mirate di dati XML.

Il risultato di una selezione, o espressione, XPath apparterrà necessariamente ad una delle tipologie di dati XML elencate di seguito:

  • Node-Set: un insieme di nodi;
  • String: un testo;
  • Boolean: true or false, vero o falso;
  • Number: un numero;

Come detto in apertura di articolo, XPath fornisce un ricco set di operatori per poter filtrare un documento XML in modo molto selettivo.
La tabella riassuntiva sotto esposta elenca tutti gli operatori XPath con il relativo modo di utilizzo all'interno di fogli di stile XSL(o XSLT), dove in alcuni casi è necessario trasformare gli operatori nelle rispettive entità.

Il file utilizzato per gli esempi è serra.xml .

Elenco degli Operatori XPath con esempi.
OperatoreDescrizioneEsempioRisultatoEspr. XSL
|Trova due o più node-set//pianta | //vasoRestituisce node-set con tutti gli elementi <pianta> e <vaso>|
+Esegue una somma3 + 25+
-Esegue una sottrazione3 - 21-
xEsegue una moltiplicazione3 x 26x
divEsegue una divisione6 div 23div
=Esegue un confronto di uguaglianzanome = 'felce'true se //pianta/nome è 'felce', altrimenti false=
!=Esegue un confronto di disuguaglianzanome != 'felce'false se //pianta/nome è 'felce', altrimenti true!=
<Esegue un confronto per Minore diprezzo < 5true se prezzo è minore di 5, altrimenti false&lt;
<=Esegue un confronto per Minore o Uguale aprezzo <= 5true se prezzo è minore o uguale a 5, altrimenti false&lt;=
>Esegue un confronto per Maggiore diprezzo > 5true se prezzo è maggiore di 5, altrimenti false&gt;
>=Esegue un confronto per Maggiore o uguale aprezzo >= 5true se prezzo è maggiore o uguale a 5, altrimenti false&gt;=
orEsegue un confronto con OR logiconome = apos;felce' or nome = 'rosa'true se //pianta/nome è 'felce' o 'rosa', altrimenti falseor
andEsegue un confronto con AND logiconome != 'felce' and nome != 'rosa'true se //pianta/nome non è ne 'felce' ne 'rosa', altrimenti falseand
modResto di divisione o Modulo6 mod 42, ovvero il resto della divisione 6/4mod

Quando si utilizzano gli operatori è importante ricordarsi che la sintassi del linguaggio XPath è case-sensitive, ovvero che ciò che è scritto in minuscolo é considerato differente da ciò che è scritto in maiuscolo.

Personalmente, trovo che l'utilizzo di tali operatori sia necessario per poter esporre dati XML tramite fogli di stile XSLT.

Alla prossima, MA.

lunedì 24 maggio 2010

XSD: Gli Indicatori di Raggruppamento

All'interno di un XSD_Schema gli Indicatori di Raggruppamento definiscono dei gruppi di elementi ComplexType o di attributi che possono poi essere utilizzati con riferimento al gruppo. Essi sono:

  • group che definisce un gruppo di elementi;
  • attributeGroup che definisce un gruppo di attributi;

Come si nota da questo frammento di codice XML:

<pianta>
  <nome>Geranio</nome>
  <esterno>true</esterno>
  <colore>rosso</colore>
</pianta>
<attrezzo>
  <nome>Zappa</nome>
  <dimensioni>30x10 cm</dimensioni>
  <materiale>acciaio</materiale>
  <util>Utilizzato per fioriere di medie 
     dimensioni e piccole profondita'</util>
  <colore>silver</colore>
</attrezzo>

In entrambi i tag <pianta> e <attrezzo> ci sono gli stessi elementi XML <nome> e <colore>. In questi casi, per migliorare la leggibilità del codice XSD ed in ottica OOP, è preferibile definire un gruppo XSD così fatto:

<xs:group name="common">  
  <xs:all> 
    <xs:element name="nome" type="xs:string" />
    <xs:element name="colore" type="xs:string" />
  </xs:all> 
</xs:group> 

Per poi referenziarlo nella definizione dei tipi complex_type pianta e attrezzo:

<xs:element name="pianta" maxOccurs="unbounded">
  <xs:complexType> 
    <xs:group ref="common" />
    <xs:element name="esterno" type="xs:boolean" />
  </xs:complexType>
</xs:element>

<xs:element name="attrezzo" maxOccurs="unbounded">
  <xs:complexType> 
    <xs:group ref="common" />
    <xs:element name="dimensioni" type="xs:string" />
    <xs:element name="materiale" type="xs:string" />
    <xs:element name="util" type="xs:string" />
  </xs:complexType>
</xs:element>

Per gli attributi funziona allo stesso modo, se si dovesse avere a che fare con attributi che figurano molteplici volte, si può scegliere di raggrupparli come mostra l'esempio seguente:

<pianta nome="Geranio" colore="rosso" />
<attrezzo nome="Zappa" colore="silver" />

Si definisce il gruppo in questa maniera:

<xs:attributeGroup name="commonAttr"> 
  <xs:attribute name="nome" type="xs:string" />
  <xs:attribute name="colore" type="xs:string" />
</xs:attributeGroup>

e lo si referenzia come di seguito:

<xs:element name="pianta" maxOccurs="unbounded">
  <xs:complexType> 
    <xs:attributeGroup ref="commonAttr" />
  </xs:complexType>
</xs:element>

<xs:element name="attrezzo" maxOccurs="unbounded">
  <xs:complexType> 
    <xs:attributeGroup ref="commonAttr" />
  </xs:complexType>
</xs:element>

Personalmente non gli ho utilizzati spesso, ma sembrano essere utili nel ridurre le righe di codice e quindi anche per rendere più ordinato lo Schema_XSD prodotto.

Alla prossima,
MA.

lunedì 10 maggio 2010

XSD: Gli Indicatori di Ordinamento

Il linguaggio XSD è utilizzato per esprimere e definire qualunque tipo di informazione tramite un XSD_Schema e quindi deve offrire tantissime funzionalità e features per poter descrivere qualunque elemento XML in maniera particolareggiata e precisa.
Tra queste particolarità vi sono gli indicatori, di vario tipo come per esempio gli indicatori_di_frequenza o gli indicatori_di_raggruppamento.

Gli Indicatori di Ordinamento vengono utilizzati all'interno della dichiarazione <xs:complexType> per stabilire l'ordine, o la sequenza, con cui devono comparire gli elementi XML all'interno del loro parent. Essi sono:

  • all;
  • sequence;
  • choice;

L'indicatore all

L'indicatore xs:all indica che gli elementi di un tipo complesso possono apparire in qualsiasi ordine. Definendo un Complex_Type in questa maniera:

<xs:complexType name="piantaItem">  
  <xs:all> 
    <xs:element name="nome" type="xs:string" /> 
    <xs:element name="esterno" type="xs:boolean" /> 
  </xs:all> 
</xs:complexType>

si stabilisce che nel documento XML è possibile avere:

<pianta>
  <nome>Geranio</nome>
  <esterno>true</esterno>
</pianta>

Ma potrebbe essere anche cosi':

<pianta>
  <esterno>true</esterno>
  <nome>Geranio</nome>
</pianta>

L'indicatore sequence

L'indicatore xs:sequence indica che gli elementi di un tipo complesso devono apparire nella esatta sequenza con cui sono stati definiti.
Se si definisce un elemento complex type in questo modo:

<xs:complexType name="piantaItem"> 
  <xs:sequence>
    <xs:element name="nome" type="xs:string" />
    <xs:element name="esterno" type="xs:boolean" />
  </xs:sequence>
</xs:complexType>

L'elemento XML dovrebbe contenere esattamente:

<pianta>
  <nome>Geranio</nome>
  <esterno>true</esterno>
</pianta>

L'indicatore choice

L'indicatore xs:choice indica che gli elementi di un tipo complesso sono alternativi tra di loro, ovvero la presenza di uno esclude automaticamente gli altri. Un elemento complex type cosi fatto:

<xs:complexType name="piantaItem"> 
  <xs:choice>
    <xs:element name="nome" type="xs:string" />
    <xs:element name="esterno" type="xs:boolean" />
  </xs:choice>
</xs:complexType>

Potrà contenere un solo elemento a scelta tra nome ed esterno:

<pianta>
  <esterno>true</esterno>
</pianta>
<pianta>
  <nome>Geranio</nome>
</pianta>
<pianta>
  <nome>Rosa</nome>
</pianta>

Concludendo, gli indicatori di Ordinamento XSD sono molti utili in quanto rendono la definizione di una struttura rigida, quale uno Schema_XSD, molto flessibile.

Alla prossima, MA.

venerdì 7 maggio 2010

XSD: Gli Indicatori di Frequenza

In questo articolo mostrerò come poter irrobustire uno Schema_XSD avvalendomi degli Indicatori di Frequenza.

Grazie ad essi è possibile stabilire la frequenza, sia massima che minima, con cui possono o devono comparire, nel file XML da validare, gli elementi XSD definiti nel proprio XSD_Schema.

Gli indicatori di frequenza sono:

  • minOccurs;
  • maxOccurs;

L'indicatore minOccurs

L'indicatore minOccurs indica il numero minimo di volte in cui un elemento XSD, complex_type o simple_type che sia, può comparire all'interno di un documento o altro elemento XML.


L'indicatore maxOccurs

Invece, l'indicatore maxOccurs indica il numero massimo di volte che l'elemento corrispondente può comparire nel documento XML.


Esempi pratici

Se si definisce un elemento complex type cosi fatto:

<xs:complexType name="piantaItem"> 
  <xs:all>
    <xs:element name="nome" type="xs:string" 
        minOccurs="1" maxOccurs="unbounded" />
    <xs:element name="esterno" type="xs:boolean" />
  </xs:all>
</xs:complexType>

E' stabilito che nel documento XML l'elemento nome deve comparire almeno 1 volta(minOccurs="1").
Invece, utilizzando l'indicatore maxOccurs valorizzato con unbounded non si pongono limiti di presenza a tale elemento.

Gli indicatori di frequenza si possono utilizzare anche all'interno di Indicatori_di_Ordinamento.
Definendo un elemento Complex Type cosi fatto:

<xs:complexType name="piantaItem"> 
  <xs:sequence maxOccurs="2">
    <xs:element name="nome" type="xs:string" />
    <xs:element name="esterno" type="xs:boolean" />
  </xs:sequence>
</xs:complexType>

E' stabilito che nel documento XML potranno figurare al massimo 2 ripetizioni dell'elemento chiamato piantaItem.

In conclusione, gli Indicatori di Frequenza sono molti utili, in quanto aumentano il controllo sull'utilizzo degli elementi XSD definiti e rendono easy il riutilizzo dell'interfaccia XSD creata.

Alla prossima, MA.

martedì 4 maggio 2010

XSD: Definire elementi Complex Types

Continuando la serie di articoli riguardanti la definizione di Schemi_XSD, oggi saranno approfonditi i vari aspetti che si dovrebbero valutare prima di fare la scelta di definire ed utilizzare Complex Types XSD.

Gli Elementi Complessi sono:

  • elementi che contengono altri elementi;
  • elementi vuoti con attributi;
  • elementi con attributi che contengono solo testo;
  • elementi che contengono altri elementi e testo;

Elementi che contengono altri elementi

Come possiamo definire un elemento cosi' fatto?

<pianta>
   <nome>Geranio</nome>
   <esterno>true</esterno>
   <colore>rosso</colore>
 </pianta>

Non c'è dubbio che si tratta di un elemento complesso che potremmo definire in questa maniera:

<xs:complexType name="piantaItem"> 
  <xs:sequence>
    <xs:element name="nome" type="xs:string" />
    <xs:element name="esterno" type="xs:boolean" />
    <xs:element name="colore" type="xs:string" />
  </xs:sequence>
</xs:complexType>

Per poi richiamarlo nella definizione dell'elemento 'Pianta':

<xs:element name="pianta" type="piantaItem" />

Da notare l'elemento <xs:sequence> che precede la definizione dei sotto-elementi e che indica che essi devono comparire nell'esatto ordine con cui sono stati definiti.

Questo elemento rientra nella sfera degli indicatori XSD.

Elementi vuoti con attributi

Vediamo come poter definire elementi che hanno attributi ma che non contengono alcun nodo figlio o Text Node come l'esempio seguente:

<webSite url="mirkoagrati.110mb.com" />

Siccome questo 'semplice' elemento contiene la definizione di un attributo, cioè un altro elemento, e' da considerarsi un complexType.

Con quale sintassi possiamo definirlo nel nostro Schema_XSD?

<xs:element name="webSite">
  <xs:complexType> 
    <xs:attribute name="url" /> 
  </xs:complexType>  
</xs:element>

Elementi con attributi che contengono solo testo

Molti documenti XML contengono nodi, o elementi, che oltre ad avere attributi hanno anche un Text-Node figlio. Un esempio di tale caso potrebbe essere il seguente:

<webSite lang="IT">
  http://mirkoagrati.110mb.com/index.php
</webSite>

La definizione XSD di questo nodo potrebbe essere:

<xs:element name="webSite">
  <xs:complexType> 
    <xs:simpleContent> 
      <xs:extension base="xs:string">  
        <xs:attribute name="lang" type="xs:string" /> 
      </xs:extension> 
    </xs:simpleContent>
  </xs:complexType>  
</xs:element>

Elementi che contengono altri elementi e testo

Potrebbe essere necessario, anche se forse è da considerarsi un caso limite (mai incontrato), definire elementi misti, ovvero che racchiudono altri elementi all'interno del proprio testo.

Un esempio potrebbe essere:

<nota> il mio cliente
  <cliente>Agrati Mirko</cliente> ha acquistato 
  <qta>13</qta> dischi <item>maxtor</item>
</nota>

Dunque, non ci sono dubbi sul fatto che abbiamo a che fare con un complexType, che tuttavia potremmo definire in questa maniera:

<xs:element name="nota">
  <xs:complexType mixed="true"> 
    <xs:sequence> 
      <xs:element name="cliente" type="xs:string" /> 
      <xs:element name="qta" type="xs:integer" /> 
      <xs:element name="item" type="xs:string" /> 
    </xs:sequence> 
  </xs:complexType> 
</xs:element>

Ovvero, e' come definire un normale elemento complesso ma utilizzando l'attributo mixed valorizzato a true in <xs:complexType>.

Alla prossima,
MA.