Newsgroup: it.comp.macintosh
Titolo: [OT] Java e XML (XSL)

In questo NG scrivono diversi programmatori veramente bravi, avrei un 
piccolo quesito OT... qualcuno di voi se ne intende della roba che ho 
scritto in oggetto? :-)
-- 
ReX

ReX <katt...@SPAMfastwebnet.it> wrote:

Di XML abbastanza, di Java il giusto (e mi schifa). Se non trovi di
meglio, provo a darti una mano.
Considera anche chiedere sul forum di faqintosh. Marco ne sa a pacchi su
XML (più di me, se è per questo) ed è meno pragmaticamente schifato da
Java.
-- 
cc = callcc {|cc| cc.call cc}; cc.call cc

 meglio, provo a darti una mano.
Io a te pensavo :-).
Ti copio&incollo quello che ho scritto anche su it.comp.java:
Ho sviluppato un programma Java che tra le varie cose si occupa di 
trasformare un file XML in HTML facendo uso di un file XSL e dando il 
tutto in pasto alle classi di libreria Xalan.
Per effettuare la trasformazione ho preso spunto da un esempio fornito 
da Xalan (vedete la fine del post).
Il mio file XML da trasformare presenta al suo interno un riferimento al 
DTD per la validazione:
<!DOCTYPE processor SYSTEM "filevalidazione.dtd">
Il problema è che quando faccio la trasformazione in Java il tutto 
funziona solo se filevalidazione.dtd si trova nella directory in cui si 
trova il file XML da trasformare (ovvio) perchè all'atto della 
trasformazione il metodo transform dell'oggetto di tipo Transformer 
cerca prima di validare il documento XML usando appunto il file indicato 
in <!DOCTYPE...>.
C'è qualche modo per specificare all'istanza di Trasformer creata da 
TrasformerFactory che voglio usare per la validazione un file dtd che si 
trova nel jar piuttosto che quello indicato in <!DOCTYPE...> ?
Ecco il codice della classe di esempio da cui ho preso spunto per 
effettuare la trasformazione XML->HTML:
public class SimpleTransform
{
     public static void main(String[] args)
     throws TransformerException, TransformerConfigurationException,
            FileNotFoundException, IOException
   {
     TransformerFactory tFactory = TransformerFactory.newInstance();
     Transformer transformer = tFactory.newTransformer(new 
StreamSource("birds.xsl"));
     transformer.transform(new StreamSource("birds.xml"), new 
StreamResult(new FileOutputStream("birds.out")));
   }
}
-- 
ReX

 trova nel jar piuttosto che quello indicato in <!DOCTYPE...> ?
Mmmm, non sono sicuro (non l'ho mai fatto) ma ho paura che ti tocchi 
separare la parte di parsing dell'xml da quella di trasformazione e 
intervenire sui parametri/impostazioni del parser. Dovrai quindi creare 
un parser e poi applicare la transform sul risultato del parser.
Se usi sax per fare parsing del file xml, c'e' questa cosa qui:
http://www.saxproject.org/apidoc/org/xml/sax/EntityResolver.html
Come scritto qui e' possibile associare una callback per leggere l'entity 
quando ti arriva la richiesta: dovrai quindi implementare questa callback 
e un InputSource Sax che legga il file direttamente dal jar in qualche 
maniera. Ovviamente dopo, visto che lanci il parser 'a mano' invece che 
usare una StreamSource nel metodo transform, dovrai usare una SaxSource 
per fare la trasformazione.
Oppure spegni la ricerca delle entity completamente se non ti serve 
realmente la validazione (anche senza validazione ti darebbe errore lo 
stesso perche' cerca ugualmente di risolvere l'entity specificata nel 
doctype). Da xalan non mi ricordo se c'e modo di farlo direttamente, ho 
paura che anche qua si tratta di intervenire sul parser separando quindi 
parsing da trasformazione e usando poi le DomSource o SaxSource. In 
xerces esiste questa feature:
Feature name :
http://apache.org/xml/features/nonvalidating/load-external-dtd
 
True:   Load the external DTD.
False:          Ignore the external DTD completely.
Default:        true
Note:   This feature is always on when validation is on. 
Che imposti col solito setFeature delle api jaxp. Se usi un altro parser 
dovrai cercare una cosa analoga nella documentazione.
-- 
Fei Fong Wong * feif...@LEVAMIDIQUAgmail.com
"That long, long memory of a dream...
Perhaps it was the memory of my soul."

 trova nel jar piuttosto che quello indicato in <!DOCTYPE...> ?
Hai dato un'occhiata alle possibilità che ti offre il metodo
setAttribute di TransformerFactory?
http://xml.apache.org/xalan-j/xsltc_usage.html
...nel paragrafo "XSLTC TransformerFactory attributes".
Eventualmente tienimi aggiornato, nel caso ti possa essere utile vado
a ripescare negli appunti.
CIAO!

 dovrai cercare una cosa analoga nella documentazione.
Ecco, questo lo uso per Xerces, ma non mi sembra di poterlo usare con 
Xalan per la trasformazione.
-- 
ReX
su Yamaha Fazer 600 '02
contatti MSN/Skype: 
kat...@inwind.it

 a ripescare negli appunti.
Casomai se mi fai il piacere te ne sarei molto grato... :-)
A me andrebbe bene sia disattivare la validazione che forzarla usando un 
file DTD diverso da quello specificato nel documenti XML da trasformare.


 file DTD diverso da quello specificato nel documenti XML da trasformare.
Mah... la soluzione che ti propongo è un po' un workaround: riesco a
fare quanto quotato sopra parsando il file xml, manipolandone il
contenuto e passando al metodo transform di Transformer una stringa
contenente l'xml opportunamente modificato.
Dal punto di vista prestazionale è ovviamente una tecnica opinabile,
soprattutto in relazione alla mole dati in gioco...penso tu possa cmq
prenderla in considerazione prima di salire sul cornicione e
commettere l'insano gesto! :-P
CIAO!

And ha scritto:

Io avevo pensato una cosa ancora più banale.
Prendo il file XML appena creato, e lo leggo (eventualmente creando una 
copia temporanea) eliminando fisicamente la linea col DOCTYPE, poi do in 
pasto questo nuovo file a Xalan che così non mi rompe con il file DTD... 
che ne dici?


 puntato da DOCTYPE?
Beh, xalan comunque crea il parser impostato di default per fare il 
parsing del file xml a cui applichi lo stylesheet (in realta' lo crea 
anche per parserizzare il file xsl), quindi 'creare' un parser tu e 
passarlo al metodo transform tramite una SAXSource o una DOMSource e' 
praticamente la stessa cosa, con in piu' il valore aggiunto di poter 
controllare come si comporta il parser: puoi disabilitare su xerces la 
feature per la ricerca delle entity (che ricordo NON e' equivalente alla 
validazione, viene fatta indipendentemente da essa: tra l'altro la 
validazione per default e' disabilitata) come ti ho indicato prima.
Non conosco modi per disattivare questa cosa direttamente da xalan e 
leggendo in giro probabilmente non e' nemmeno possibile.
Per forzare l'uso di un file esterno, lui lo fa gia': va a cercare un 
file con il nome specificato nel doctype nella directory di lavoro 
corrente.
Qui sotto un esempio, va impostata la proprieta' della virtual machine 
per specificare il parser sax da usare, da invocazione java si puo' 
impostare ad esempio cosi':
java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser 
SimpleTransform
---------------
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
public class SimpleTransform
{
  public static void main(String[] args)
      throws TransformerException, TransformerConfigurationException,
             FileNotFoundException, IOException, SAXException
  {
    XMLReader parser = XMLReaderFactory.createXMLReader();
    parser.setFeature("
http://apache.org/xml/features/nonvalidating/load-
external-dtd", false);
 
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer(new 
                                                      StreamSource
("birds.xsl"));
    transformer.transform(new SAXSource(parser, new InputSource(new 
FileInputStream("birds.xml"))), new 
                          StreamResult(new FileOutputStream
("birds.out")));


 che ne dici?
Se la dimensione dei file xml da trattare è ragionevole, non vedo
assolutamente problemi!
Ciao e buon lavoro!