Utilizzare le funzioni XPath integrate

Durante lo sviluppo di uno dei corsi di formazione online Altova, ho ordinato un elenco di libri in base agli autori. Ho notato che il campo "autore" conteneva una stringa con il nome completo dell'autore, quindi i libri venivano ordinati in base alla prima lettera della stringa, ovvero al nome dell'autore. Non era possibile correggere l'ordinamento nel contesto del corso, ma è possibile estrarre facilmente il cognome da una stringa e utilizzarlo come chiave di ordinamento utilizzando le funzioni XPath. Se si utilizzano poi i titoli dei libri come chiave di ordinamento secondaria, si riscontra un problema con i titoli che iniziano con "A", "An" o "The". Vorrei utilizzare il titolo come chiave di ordinamento secondaria, ma ignorando gli articoli determinativi o indeterminativi all'inizio.

Esaminiamo come abbiamo creato questo codice XSLT. Questo articolo è stato scritto utilizzando XMLSpy come piattaforma, ma le stesse espressioni XPath possono essere utilizzate all'interno di MapForce o StyleVision per ottenere risultati simili. Possiamo iniziare con una semplice lista di libri in formato XML. Abbiamo 4 libri, ciascuno con i nodi "autore" e "titolo".

Un codice XSLT per creare un elenco di libri potrebbe essere simile a questo:

Questo genererà il seguente risultato:

I libri vengono generati nell'ordine in cui compaiono nel file di dati originale. Se aggiungiamo l'elemento xsl:sort all'interno del ciclo xsl:for-each, possiamo organizzare l'output in modi diversi.

Questo genererà un elenco ordinato, ma non correttamente ordinato.

Ordinare gli autori come stringhe di testo fa sì che "Jules Verne" appaia prima di "Mark Twain". Inoltre, "A Connecticut Yankee in King Arthur’s Court" appare prima di "Adventures of Huckleberry Finn". Vogliamo ignorare l'articolo indeterminativo "A", in modo che "Adventures of Huckleberry Finn" appaia prima di "A Connecticut Yankee in King Arthur’s Court". Possiamo utilizzare espressioni XPath per estrarre le chiavi di ordinamento che desideriamo.

Esaminiamo il codice prima di analizzare l'output. Sostituiamo "author" con "reverse(tokenize(author, ' '))[1]". La funzione "tokenize" divide la stringa "author" in token, utilizzando uno spazio singolo come separatore. Quindi, "Jules Verne" viene suddiviso in "Jules" e "Verne". La funzione "reverse" inverte l'ordine dei token, ottenendo "Verne" e "Jules". L'elemento tra parentesi quadre seleziona il primo elemento della lista, ovvero "Verne". Questo è il valore utilizzato dalla funzione xsl:sort per ordinare i libri. Non è la soluzione perfetta, ma funziona nel nostro caso. Il titolo sembra complesso, ma la logica è semplice. L'espressione "tokenize(title, ' ')[1]" estrae la prima parola del titolo. Quindi, il primo test "if" è: "La prima parola del titolo è la parola 'A'?". Se lo è, restituiamo la sottostringa del titolo che inizia con la sua terza lettera, eliminando così "A" e lo spazio. Se la prima parola del titolo non è "A", dobbiamo eseguire un altro test per vedere se la prima parola del titolo è "The". Se lo è, utilizziamo la sottostringa del titolo che inizia con il suo quinto carattere, eliminando così "The" e uno spazio. Se entrambi i test falliscono, passiamo semplicemente il titolo come chiave di ordinamento. Potremmo aggiungere un altro test al nostro codice per vedere se la prima parola è "An", ma non è necessario per questo set di dati. Eseguendo quest'ultima trasformazione XSLT, otteniamo il seguente output.

"Mark Twain" ora precede "Jules Verne". "Le avventure di Huckleberry Finn" appare prima di "Il famoso rospo saltatore della contea di Calaveras" e "Un americano a corte di Re Artù". Il problema nel nostro approccio alla stringa dell'autore è che vogliamo che "Jules Verne" sia trattato come "Verne, Jules" per l'ordinamento, in modo che, se avessimo un libro di "Jimmy Verne", questi venisse considerato un autore diverso. Il nostro codice non lo fa. L'utilizzo di "concat(reverse(tokenize(author, ' '))[1], reverse(tokenize(author, ' '))[2])" ordinerebbe correttamente "Jules Verne" e "Jimmy Verne", ma questa soluzione funzionerebbe solo con nomi di due parole. Se un autore avesse un suffisso ("Martin Luther King, Jr.") o più parole ("George Herbert Walker Bush"), il codice non funzionerebbe. Esistono molte eccezioni alle regole generali sull'ordinamento dei nomi, e il codice necessario per gestire tutte le varianti andrebbe ben oltre lo scopo di questo articolo. Volevamo dimostrare la possibilità di manipolare i dati XML in tempo reale utilizzando espressioni XPath. Non sempre abbiamo il controllo completo sul formato delle nostre fonti di dati, ma utilizzando la potenza delle espressioni XPath, possiamo trasformare i dati nel formato che ci serve. Una copia dei file utilizzati in questi esempi è disponibile qui.