OVH Cloud OVH Cloud

Parser un flux XML en java

3 réponses
Avatar
Xavier Seneque
Bonjour tout le monde,
j'en viens à vous apres des recherches infructeuses sur de multiples
supports...

je souhaite créer un un serveur qui reçoit un flux au format XML, et
profiter de l'existence de parsers XML java pour l'analyser à moindre
frais !

mais bon, j'ai quelques problemes.

d'apres moi voilà quelques generalites sur la chose :

la DTD decrivant ce que le serveur doit recevoir serait du cote serveur,
non ?
ensuite, le flux que le serveur reçoit ne doit pas faire de reference
explicite à une DTD, ni meme en definir une lui meme, sinon, le client
pourrait definir lui meme le format de ce qu'il envoie, et ça, je veux pas !

donc d'apres ces simples constats...j'ai commencé à faire un truc qui
arrive à parser un flux XML bien formé, mais qui n'est validé par aucune
DTD...

pour commencer voilà ma DTD toute simple :

//debut DTD
<?xml version='1.0' encoding='UTF-8' ?>
<!ELEMENT session (query_get_im_srv)>
<!ELEMENT query_get_im_srv (user)>
<!ELEMENT user (#PCDATA)>
//fin DTD

donc en gros le client doit recevoir un message comme cela :
<session><query_get_im_srv><user>toto</toto></query_get_im_srv></session>

pour parser du xml seulement bien formé je fais comme ça actuellement (
j'utilise SAX, vu que je fais que lire ) :

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
saxParser = factory.newSAXParser();
saxParser.parse(new InputSource(stream),handler);
// stream est une reference vers le flux d'entree
// handler est la classe heritant de DefaultHandler qui surcharge les
callbacks appelés lors du parsage

j'ai cru comprendre que pour valider un flux, il fallait faire qlq chose
de ce style :

SchemaFactory sf =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema s = sf.newSchema( new File("madtd.dtd") );
Validator validator = s.newValidator();
validator.validate(xmlSource);

or ce code me genere une jolie exception :
--> org.xml.sax.SAXParseException: The markup in the document preceding
the root element must be well-formed.

qui d'apres mes connaissance en anglais me dis que la balise precedent
l'element racine doit etre bien formée... mais cela ne m'avance pas trop !

j'en viens donc vous demander si vous avez une idée d'où peut venir
cette exception ( mon DTD, mon code ... ? ), si je me plante totallement
de methode ? comment vous faites/feriez vous ? autres conseils ?

merci d'avance.

xavier seneque

3 réponses

Avatar
Jacques Desmazieres
Supprime le commentaire avant la balise <?xml et ça devrait le faire

Jacques Desmazières
"Xavier Seneque" a écrit dans le message de
news: 421cde8c$0$19299$
Bonjour tout le monde,
j'en viens à vous apres des recherches infructeuses sur de multiples
supports...

je souhaite créer un un serveur qui reçoit un flux au format XML, et
profiter de l'existence de parsers XML java pour l'analyser à moindre
frais !

mais bon, j'ai quelques problemes.

d'apres moi voilà quelques generalites sur la chose :

la DTD decrivant ce que le serveur doit recevoir serait du cote serveur,
non ?
ensuite, le flux que le serveur reçoit ne doit pas faire de reference
explicite à une DTD, ni meme en definir une lui meme, sinon, le client
pourrait definir lui meme le format de ce qu'il envoie, et ça, je veux pas
!


donc d'apres ces simples constats...j'ai commencé à faire un truc qui
arrive à parser un flux XML bien formé, mais qui n'est validé par aucune
DTD...

pour commencer voilà ma DTD toute simple :

//debut DTD
<?xml version='1.0' encoding='UTF-8' ?>
<!ELEMENT session (query_get_im_srv)>
<!ELEMENT query_get_im_srv (user)>
<!ELEMENT user (#PCDATA)>
//fin DTD

donc en gros le client doit recevoir un message comme cela :
<session><query_get_im_srv><user>toto</toto></query_get_im_srv></session>

pour parser du xml seulement bien formé je fais comme ça actuellement (
j'utilise SAX, vu que je fais que lire ) :

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
saxParser = factory.newSAXParser();
saxParser.parse(new InputSource(stream),handler);
// stream est une reference vers le flux d'entree
// handler est la classe heritant de DefaultHandler qui surcharge les
callbacks appelés lors du parsage

j'ai cru comprendre que pour valider un flux, il fallait faire qlq chose
de ce style :

SchemaFactory sf > SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema s = sf.newSchema( new File("madtd.dtd") );
Validator validator = s.newValidator();
validator.validate(xmlSource);

or ce code me genere une jolie exception :
--> org.xml.sax.SAXParseException: The markup in the document preceding
the root element must be well-formed.

qui d'apres mes connaissance en anglais me dis que la balise precedent
l'element racine doit etre bien formée... mais cela ne m'avance pas trop !

j'en viens donc vous demander si vous avez une idée d'où peut venir
cette exception ( mon DTD, mon code ... ? ), si je me plante totallement
de methode ? comment vous faites/feriez vous ? autres conseils ?

merci d'avance.

xavier seneque


Avatar
Xavier Seneque
Jacques Desmazieres wrote:
Supprime le commentaire avant la balise <?xml et ça devrait le faire

Jacques Desmazières


je n'ai mis ce commentaire dans ce post qu'à des fins informatives, il
n'est pas dans le fichier .dtd ...

Avatar
Rémi Cocula

SchemaFactory sf > SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema s = sf.newSchema( new File("madtd.dtd") );
Validator validator = s.newValidator();
validator.validate(xmlSource);

or ce code me genere une jolie exception :
--> org.xml.sax.SAXParseException: The markup in the document preceding
the root element must be well-formed.



perso je ne connais pas SAX car je travaille toujours avec DOM...
...mais ...
regarde bien la doc de SchemaFactory.
Vu que ça s'appelle ShemaFactory je me demande si tu peux t"en servir avec
une DTD.

Attention à ne pas confondre DTD et Schema XML (c'est pas du tout la même
chose).