Shredding XML tramite XSLT in Java

Devo trasformare grandi file XML che hanno una struttura nidificata (gerarchica) del modulo

 Flat XML Hierarchical XML (multiple blocks, some repetitive) Flat XML  

in una forma più piatta (“triturata”), con 1 blocco per ogni blocco annidato ripetitivo.

I dati hanno numerosi tag e varianti di gerarchia diversi (specialmente nel numero di tag dell’XML triturato prima e dopo l’XML gerarchico), quindi idealmente non si dovrebbe fare alcuna ipotesi sui nomi di tag e attributi o sul livello gerarchico.

Una visualizzazione di livello superiore della gerarchia per soli 4 livelli sarebbe simile

  ...  ...  ... A B ...  ...  ...  

e l’output desiderato sarebbe allora

  ...  ...  ... A ...  ...  ...   ...  ...  ... B ...  ...  ...  

Cioè, se ad ogni livello i ci sono componenti Product(Li) diversi, verrà prodotto un totale di componenti Product(Li) diversi (solo 2 sopra, poiché l’unico fattore di differenziazione è Livello 4, quindi L1*L2*L3*L4 = 2 ).

Da quello che ho visto in giro, XSLT potrebbe essere la strada da percorrere, ma qualsiasi altra soluzione (ad esempio, StAX o anche JDOM) farebbe.

Un esempio più dettagliato, utilizzando informazioni fittizie, sarebbe

  
123 A Street
28 List of previous jobs in the US 3 01/10/2001 38 01/12/2004 6 01/06/2005 10 List of previous jobs in the UK 2 01/05/1999 25 01/07/2001 3 true 6

I suddetti dati dovrebbero essere divisi in 5 blocchi (cioè uno per ogni diverso blocco ), ognuno dei quali lascerà tutti gli altri tag identici e avrà solo un singolo elemento . Quindi, dati i 5 diversi blocchi nell’esempio sopra, l’XML trasformato (“triturato”) sarebbe

  
123 A Street
28 List of previous jobs in the US 3 01/10/2001 38 true 6
123 A Street
28 List of previous jobs in the US 3 01/12/2004 6 true 6
123 A Street
28 List of previous jobs in the US 3 01/06/2005 10 true 6
123 A Street
28 List of previous jobs in the UK 3 01/05/1999 25 true 6
123 A Street
28 List of previous jobs in the UK 3 01/07/2001 3 true 6

Dato il seguente XML:

   
123 A Street
28 List of previous jobs in the US 3 01/10/2001 38 01/12/2004 6 01/06/2005 10 List of previous jobs in the UK 2 01/05/1999 25 01/07/2001 3 true 6

Il seguente XSLT:

              

Fornisce il seguente risultato:

    
123 A Street
28 List of previous jobs in the US 3 01/10/2001 38 true 6
123 A Street
28 List of previous jobs in the US 3 01/12/2004 6 true 6
123 A Street
28 List of previous jobs in the US 3 01/06/2005 10 true 6
123 A Street
28 List of previous jobs in the UK 2 01/05/1999 25 true 6
123 A Street
28 List of previous jobs in the UK 2 01/07/2001 3 true 6

Si noti che ho aggiunto un elemento radice di output per garantire che il documento sia ben formato.

Questo è quello che volevi?

Potresti anche essere in grado di usare xsl: copy per copiare gli elementi di livello superiore, ma ho bisogno di pensarci un po ‘di più. Con il precedente xslt, hai più controllo, ma devi anche ridefinire i tuoi elementi …

Ecco una soluzione generica come richiesto :

                                           

Se applicato sul documento XML semplificato (e generico) fornito :

  ...  ...  ... A B ...  ...  ...  

il risultato voluto e corretto è prodotto :

  ...  ...  A  ...  ...   ...  ...  B  ...  ...  

Ora, se cambiamo la linea :

   

a:

   

e applicare la trasformazione al documento XML Employee :

  
123 A Street
28 List of previous jobs in the US 3 01/10/2001 38 01/12/2004 6 01/06/2005 10 List of previous jobs in the UK 2 01/05/1999 25 01/07/2001 3 true 6

otteniamo nuovamente il risultato voluto e corretto :

   
123 A Street
28 List of previous jobs in the US 3 01/10/2001 38 true 6
123 A Street
28 List of previous jobs in the US 3 01/12/2004 6 true 6
123 A Street
28 List of previous jobs in the US 3 01/06/2005 10 true 6
123 A Street
28 List of previous jobs in the UK 2 01/05/1999 25 true 6
123 A Street
28 List of previous jobs in the UK 2 01/07/2001 3 true 6

Spiegazione : L’elaborazione viene eseguita in un modello denominato ( StructRepro ) e controllata da un singolo parametro esterno denominato pLeafNodes , che deve contenere un nodeset di tutti i nodes la cui “struttura verso l’alto” deve essere riprodotta nel risultato.