Accueil
 chercher             Plan du site             Info (English version) 
L'histoire de XML s'écrit en ce moment même. XMLfr vous aide à la suivre et à en dégager les tendances.Les listes de discussions XMLfr sont à votre disposition pour réagir sur nos articles ou simplement poser une question.Si vous ètes passionnée(e) par XML, pourquoi ne pas en faire votre métier ?XMLfr n'est heureusement pas le seul site où l'on parle de XML. Découvrez les autres grâce à XMLfr et à l'ODP.Les partenaires grâce auxquels XMLfr peut se développer.Pour tout savoir sur XMLfr.XMLfr sans fil, c'est possible !Pour ceux qui veulent vraiment en savoir plus sur XML.L'index du site.
 Si vous vous posez une question, vous n'êtes peut-être pas le premier...Les traductions en français des bibles XML.Ces articles sont des références dans leur domaine.Tout ce qu'il faut savoir pour démarrer sur un sujet XML...


Foire aux questions de Java pour XML

Java, portabilité pour les procédés, XML, portabilité pour les documents ; dans cette FAQ, les meilleures solutions pour le mariage.

Par Hervé AGNOUX, de la SARL diaam informatique (http://www.diaam-informatique.com/).
mardi 20 juillet 2004

Table des matières

Préambule

Généralités et premiers secours sur JAXP

JAXP c'est quoi ?

Je suis un spécialiste JAXP, mais je n'arrive à rien faire. Pourquoi ?

Comment faire pour valider un document ?

Comment faire pour valider un document alors que il n'a pas de DTD ?

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Mon fichier XML est très, très, très gros. Que puis-je faire ?

Modifier un document XML (DOM)

Comment puis-je extraire un élément d'un document pour en faire un nouveau document ?

Comment faire pour mettre toutes les valeurs d'un élément dans une liste !?

A quoi correspondent tous ces noms pour les éléments ?

Comment puis-je mémoriser dans un fichier un document XML que j'ai construit à l'aide de DOM ?

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Comment faire pour valider un document avec DOM ?

Réagir à toute allure au parcours d'un document XML (SAX)

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Puis-je connaître la ligne et la colonne des noeuds que je suis en train d'analyser ?

Comment faire pour valider un document avec SAX ?

Transformer un document XML... en un document XML (XSLT)

Comment puis-je lancer l'exécution d'une transformation XSLT avec un programme java ?

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Divers

Que d'encodings, que d'encodings, que d'encodings !

... et pourtant, certains caractères semblent être refusés par les parsers, alors que je les ai mis dans une section CDATA. Que faire ?

Je voudrais mettre une image dans mon XML et / ou / surtout des données binaires. Que faire ?

Je n'ai pas trouvé de réponse à mon problème dans cette FAQ, et je ne comprends rien à l'anglais ! Que faire ?

Préambule

Il n'y a pas que Java dans le monde des procédés et procédures... La plupart des questions posées ici pourraient simplement être enrichies en remplaçant Java par Perl, C, VB, Delphi, et ainsi de suite. De même, en Java, il n'y a pas que JAXP, mais il existe aussi de nombreuses autres approches dans le traitement des documents XML : DOM4J, bien sûr, et JAXB, et quantité de J**X**. Mais je suis incapable de présenter toutes ces technologies. Si cela vous intéresse de faire la FAQ de l'une, écrivez-nous : redacteurs@xmlfr.org.

J'ai choisi de garder les noms anglais pour tout ce qui ne veut pas dire grand chose en français. Vous trouverez donc des factories, des beans, et ainsi de suite.

La version de Java couverte par cette FAQ est le J2SE 1.4.2.

Généralités et premiers secours sur JAXP

JAXP c'est quoi ?

Un ensemble de paquetages Java, intégrés au JDK depuis la version 1.4, pour gérer le XML. JAXP signifie "Java API for XML Processing".

La version 1.4.2 de J2SE (la version couverte dans cette FAQ) comprend DOM2, SAX2, et XSLT 1.0. (Voir une version française des spécifications du W3C à la Liste des traductions françaises disponibles des documents W3C).

Il est prévu que le J2SE 1.5.0 comprenne DOM3, SAX 2.0.1, XSLT 1.0. Avec le J2SE 1.5 il y aura également un paquetage pour les validations, les espaces de noms, et XPath.

Je suis un spécialiste JAXP, mais je n'arrive à rien faire. Pourquoi ?

Vous devez encore devenir un spécialiste XML !

JAXP vous permet d'informatiser le traitement des documents XML, mais ne vous dit rien de la façon dont ces documents doivent être organisés. Vous devrez par exemple choisir un vocabulaire, un schéma, un langage de schémas, déterminer comment il sera placé sur un réseau, déterminer les espaces de noms utilisés... Toutes choses pour lesquelles JAXP ne vous sera d'aucun secours.

Comment faire pour valider un document ?

Vous pouvez le faire, uniquement lors de l'analyse du document, avec SAX ou avec DOM.

Pour les deux voies il faut opérer de façon similaire, en plaçant la propriété validating des factories à vrai.

Avec le J2SE seul, il n'est possible de valider qu'à partir de DTD.

Comment faire pour valider un document alors que il n'a pas de DTD ?

Vous savez, bien sûr que, en théorie, un document qui n'a pas de DTD ne peut être validé... Néanmoins, voici comment faire tout de même ; le source complet est com/diaam/xmlfr/faqjaxp/MetDTD.java.

Il s'agit de lancer deux threads : le premier pour placer une DTD dans le document, le deuxième pour valider.

Le premier thread est une transformation, qui est orientée, dans le constructeur de ce thread, pour placer la DTD :

    CoursePourPlacerDTD
    (String nomFichierXML, String nomFichierDTD, Result résultat)
 
    throws Exception
    {
      FileInputStream fichierXML;
      TransformerFactory fabrique;
    
      fichierXML = new FileInputStream(nomFichierXML);
      fabrique = TransformerFactory.newInstance();
      m_transfo = fabrique.newTransformer();
      m_transfo.setOutputProperty(
  /***/ OutputKeys.DOCTYPE_SYSTEM, nomFichierDTD);
      m_source = new StreamSource(fichierXML);
      m_résultat = résultat;
    }

A ce niveau, nous ne donnons que le nom du fichier DTD. C'est celui qui sera inscrit dans le fichier XML. Plus tard, pour la validation, il faudra indiquer au système où se trouve ce fichier, en renseignant systemId.

Le deuxième thread est une simple lecture validante du flux issu de la transformation précédente , elle aussi préparée dans le constructeur du thread :

    CoursePourValider(InputSource fluxAValider) throws Exception
    {
      SAXParserFactory fabriquePilotes;
      SAXParser piloteValidant;
      
      fabriquePilotes = SAXParserFactory.newInstance();
      fabriquePilotes.setValidating(true);
      m_pilote = fabriquePilotes.newSAXParser();
      m_fluxLecture = fluxAValider;
    }

Ces préparations faites, il faut régler les flux, et notamment le pipe qui va du premier thread au second.

    pipeEcrit = new PipedOutputStream();
    pipeLu = new PipedInputStream(pipeEcrit);

Le premier thread émet dans le pipe un StreamResult (une série d'octets) :

    fluxAvecDTD = new PrintStream(pipeEcrit);
    résultatAvecDTD = new StreamResult(fluxAvecDTD);

Et le second lira ce pipe, en le voyant comme une source SAX ; de plus, on utilise la position du fichier XML pour situer le fichier DTD :

    entréeAvecDTD = new InputSource(pipeLu);
    entréeAvecDTD.setSystemId
  (propsFichierXML.getParentFile().toURL().toString());

Il ne restera plus alors qu'à lancer les threads correspondants.

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Voici comment faire avec DOM, avec SAX, et avec XSLT.

Mon fichier XML est très, très, très gros. Que puis-je faire ?

Dans la boîte à outils JAXP, seule la technologie SAX est adaptée au traitement des gros fichiers XML. Vous ne pouvez employer ni DOM, ni XSLT.

Modifier un document XML (DOM)

Comment puis-je extraire un élément d'un document pour en faire un nouveau document ?

Soit e l'élément que vous voulez transformer en document. Vous allez utiliser la transformation identité d'un objet DOM vers un autre objet DOM.

Voici comment :

DOMSource source = new DOMSource(e);
// remarquez que le résultat est vide au départ.
DOMResult resultat = new DOMResult(); 
TransformerFactory fabrique = TransformerFactory.newInstance();
Transformer trans = fabrique.newTransformer();
trans.transform(source, resultat);
//... et maintenant, dans resultat.getNode() 
// il y a un Document DOM, copie de // votre Element DOM d'origin
e. (le DOM, c'est simple ! ).

Comment faire pour mettre toutes les valeurs d'un élément dans une liste !?

Avec le fichier XML suivant :

<?xml version="1.0" encoding="ISO-8859-1"?>
<poème titre="Une pierre" auteur="Yves Bonnefoy">
  <verset>Le jour au fond du jour sauvera-t-il</verset>
  <verset>Le peu de mots que nous fûmes ensemble ?</verset>
  <verset>
    Pour moi, j'ai tant aimé ces jours confiants, je veille
  </verset>
  <verset>
    Sur quelques mots éteints dans l'âtre de nos coeurs.
  </verset>
</poème>

... et le code source suivant :

package com.diaam.xmlfr.faqsax;

import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class MettreValeursEnListe
{
  public static void main(String[] args) throws Exception
  {
    DocumentBuilder constructeur;
    Document dom;
    NodeList listeElementsEnDOM;
    ArrayList liste;
    
    constructeur = DocumentBuilderFactory.newInstance().
  /***/ newDocumentBuilder();
    dom = constructeur.parse(args[0]);
    listeElementsEnDOM = dom.getElementsByTagName("*");
    liste = new ArrayList();
    for (int i = 0; i < listeElementsEnDOM.getLength(); i++)
    {
      if (listeElementsEnDOM.item(i).getChildNodes().getLength() 
== 1)
      {
  Text texte;
  
  texte = (Text)listeElementsEnDOM.item(i).getChildNodes().item(0
);
  liste.add(texte.getNodeValue());
      }
    }
    System.out.println("liste="+liste);
  }
}

... nous obtenons le résultat suivant :

liste=[Le jour au fond du jour sauvera-t-il, Le peu de mots que n
ous fûmes ensemble ?, Pour moi, j'ai tant aimé ces jours confiant
s, je veille, Sur quelques mots éteints dans l'âtre de nos coeurs
.]

Cet exemple présente les choses de façon simpliste, et n'a aucune prétention à être général. En particulier, il ne gère pas les cas où la distribution des noeuds dans le document serait plus complexe.

A quoi correspondent tous ces noms pour les éléments ?

Soit l'élément XML <bb:b xmlns:bb="http://bb"/> ; soit e la variable DOM qui le contient.

Dans ce cas :

  • e.getTagName() renvoit bb:b.
  • e.getNamespaceURI() renvoit http://bb.
  • e.getLocalName() renvoit b.
  • e.getPrefix() renvoit bb.

Comment puis-je mémoriser dans un fichier un document XML que j'ai construit à l'aide de DOM ?

Admettons que votre document soit dans une variable DOM. Vous allez utiliser les transformations pour le placer d'un source DOM vers un résultat flux, résultat que vous orienterez vers un fichier, ou toute autre destination. Pour la transformation, vous appliquerez la transformation identité.

Voici :

DOMSource domSource = new DOMSource(dom);
StreamResult fluxDestination = new StreamResult(new File("votrefi
chier.xml"));
TransformerFactory fabrique = TransformerFactory.newInstance();
Transformer transformationIdentité = fabrique.newTransformer();
transformationIdentité.transform(domSource, fluxDestination);

Vous pouvez adapter le flux destinations en utilisant différentes clefs, que vous trouverez dans javax.transform.OutputKeys. Par exemple, pour que le fichier destination soit indenté, et soit encodé ISO-8859-1 :

Transformer transformationIdentité = fabrique.newTransformer();
transformationIdentité.setOutpuProperty(OutputKeys.INDENT, "yes")
;
transformationIdentité.setOutpuProperty(OutputKeys.ENCODING, "ISO
-8859-1");
transformationIdentité.transform(domSource, fluxDestination);

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Le XML stipule que les espaces blancs doivent tous être présentés à l'application qui interprète le document. A l'application, donc, à vous.

Si votre document est valide, vous avez une option facile : activez la méthode setIgnoringElementContentWhitespace de la classe javax.xml.parsers.DocumentBuilderFactory.

Sinon, si votre document est juste bien formé, voici un petit exercice de style DOM ; la méthode clef est la méthode importNode de la classe org.w3c.dom.Document :

  /**
   * Renvoie un Document, copie de celui passé en paramètre, dont
 tous les noeuds
   * textes composés seulement d'espaces blancs ont été retirés.
   *
   */
  public Document sansBlancs(Document origine)
  {
    Document résultat;
    résultat = null;
    try
    {
      Element eSrc, eDest;
      DocumentBuilderFactory dbf;
      DocumentBuilder db;
      NodeList nl;
      // construction du nouveau DOM
      dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(true);
      db = dbf.newDocumentBuilder();
      résultat = db.newDocument();
      // recopie du noeud racine
      eSrc = origine.getDocumentElement();
      eDest = (Element)d.importNode(eSrc, false);
      d.appendChild(eDest);
      nl = eSrc.getChildNodes();
      // copie du reste.
      copieSansBlancs(eDest, nl, d);
    }
    catch (ParserConfigurationException pce)
    {
      IllegalStateException ise;
      ise = new IllegalStateException(pce.toString());
      ise.initCause(pce);
      throw ise;
    }
    return résultat;
  }

  private void copieSansBlancs
  (Node destination, NodeList eux, Document importateur)
  {
    for (int i = 0; i < eux.getLength(); i++)
    {
      Node nOri, nCop;
      boolean b;
      b = true;
      nOri = eux.item(i);
      if (nOri.getNodeType() == Node.TEXT_NODE)
        if (nOri.getParentNode().getNodeType() == Node.ELEMENT_NO
DE)
        {
          Text t;
          t = (Text)nOri;
          if (t.getData().trim().length() == 0)
            b = false;
        }
      if (b)
      {
        nCop = importateur.importNode(nOri, false);
        destination.appendChild(nCop);
        copieSansBlancs(nCop, nOri.getChildNodes(), importateur);
      }
    }
  }

Cet exemple présente les choses de façon simpliste, et n'a aucune prétention à être général. En particulier, il ne gère pas les cas où la distribution des noeuds dans le document serait plus complexe, et comporterait par exemple des noeuds commentaires, ou des noeuds instructions de traitement.

Notez que DOM3 présente des fonctions approchantes, comme par exemple isElementContentWhitespace.

Comment faire pour valider un document avec DOM ?

Vous pouvez le faire, uniquement lors de l'analyse du document, avec SAX ou avec DOM.

Il faut placer la propriété validating de la DocumentBuilderFactory à vrai :

    DocumentBuilderFactory factory =
    DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    factory.setValidating(true);

Réagir à toute allure au parcours d'un document XML (SAX)

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Le XML stipule que les espaces blancs doivent tous être présentés à l'application qui interprète le document. A l'application, donc, à vous.

Pour se faire, avec SAX, nous utilisons un filtre SAX. Ce composant se comporte à la fois comme un consommateur d'évènements (pour nous il reçoit le lecteur du fichier brut), et à la fois comme un lecteur de fichier XML (pour nous, il publiera les événements... sauf ceux qui concernent les éléments textes composés uniquement d'espaces blancs).

Le source complet est com/diaam/xmlfr/faqjaxp/SansBlancsAvecSax.java. Vous pouvez utiliser en lui passant en paramètre le fichier XML auquel il faut retirer les espaces blancs (java com.diaam.xmlfr.faqsax.SansBlancsAvecSax unfichier.xml).

En voici les extraits les plus intéressants.

Le document XML passe à travers 3 filtres. Le premier permet de s'assurer que les filtres suivants recevront chaque noeud texte en une seule fois, ce qui facilite les traitements. Le second supprime les noeuds textes composés uniquement d'espaces blancs, et le troisième, enfin, génère le fichier XML attendu.

Pour le premier, il s'agit simplement de rassembler les caractères dans un buffer, et de les rediffuser lors de l'événement fin :

    public void characters(char[] ch, int start, int length) 
    throws SAXException
    {
      m_rangeTexte.append(ch, start, length);
    }
    
    public void endElement(String uri, String localName, String q
Name) 
    throws SAXException
    {
      // l'élément est fini, donc on est sûr que l'on
      // ne recevra plus de caractères ;
      // on diffuse les caractères reçus.
      if (m_rangeTexte.length() > 0)
      {
  String tousCaractèresTrim;
  String tousCaractères;
  
  tousCaractères = m_rangeTexte.toString();
  getContentHandler().
  characters(tousCaractères.toCharArray(), 0, tousCaractères.leng
th());
  m_rangeTexte.setLength(0);
      }
      
      // et on diffuse l'événement de fin.
      getContentHandler().endElement(uri, localName, qName);
    }

On remarquera que ce filtre désynchronise les événements characters et endElement, pour ne les rediffuser que lors de la réception de endElement. getContentHandler est le deuxième filtre. Et on remarque aussi que, une fois la rediffusion faite, le buffer d'accumulation (m_rangeTexte) est vidé.

Le deuxième filtre, assuré de recevoir chaque élément texte en une seule fois, ne le rediffuse que s'il est composé d'autre chose que d'espaces blancs :

    // dans le cas où il n'y a que des blancs, ne renvoie rien, 
    // sinon renvoit l'original.
    public void characters(char[] ch, int start, int length) 
    throws SAXException
    {
      String texte;
      
      texte = new String(ch, start, length);
      if (texte.trim().length() > 0)
    getContentHandler().characters(ch, start, length);
    }

Enfin, le troisième filtre est une simple transformation identité, qui renvoit le flux vers la sortie standard :

    // Pour voir le fichier résultat, j'utilise une transformatio
n
    // à l'identique sur le filtre ; le transformer se déclarera
    // lui même comme ContentHandler de la source SAX, donc du fl
itre.
    source = new SAXSource(filtreBlancs, fluxEntrant);
    print = new StreamResult(System.out);
    identité = TransformerFactory.newInstance().newTransformer();
    identité.transform(source, print);

Il est nécessaire de coordonner les différents filtres, pour que la sortie de l'un correspondre à l'entrée du suivant. Pour ce faire, il suffit de ce souvenir qu'un filtre fonctionne à la fois comme lecteur du précédent et comme émetteur pour le suivant, ce qui se règle en initialisant l'un avec le précédent ; voici le constructeur pour le filtre ôtant les blancs, par exemple :

    private FiltreOtantLesBlancs(XMLReader parent)
    {
      super(parent);
    }

Ceci enregistre le filtre ôtant les blancs comme ContentHandler du précédent filtre, c'est à dire du filtre rassemblant les textes.

Puis-je connaître la ligne et la colonne des noeuds que je suis en train d'analyser ?

Peut être... Avec le Locator. Celui fournit par le JDK donne bien la ligne, mais pas la colonne... rien n'est parfait.

A toutes fins utiles, essayez le programme suivant :

package com.diaam.xmlfr.faqsax;

import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;


public class LigneColonne
{
  // en premier paramètre, le fichier XML.
  public static void main(String[] args) throws Exception
  {
    SAXParser piloteSAX;
    
    piloteSAX = SAXParserFactory.newInstance().newSAXParser();
    piloteSAX.parse(new File(args[0]), new DonneLigneColonne()); 
  }
  
  private static class DonneLigneColonne 
  extends org.xml.sax.helpers.DefaultHandler
  {
    private Locator m_locator;
    
    // s'il le parser gère les lignes et colonnes,
    // il doit appeler cette méthode
    // avant de commencer son travail.
    public void setDocumentLocator(Locator locator)
    {
      m_locator = locator;
    }
    
    public void startElement
    (String uri, String localName, String qName, Attributes attri
butes)
    {
      if (m_locator == null)
    System.err.println
          ("Non d'un chien ! Le parser ne provide pas de locator 
! ");
  else
    System.out.println
    ("element = "+qName+
    ", ligne="+m_locator.getLineNumber()+
    ", colonne="+m_locator.getColumnNumber());
    }
  }
}

Comment faire pour valider un document avec SAX ?

Vous pouvez le faire, uniquement lors de l'analyse du document, avec SAX ou avec DOM.

Il faut placer la propriété validating de la SAXParserFactory à vrai :

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);

Transformer un document XML... en un document XML (XSLT)

Comment puis-je lancer l'exécution d'une transformation XSLT avec un programme java ?

A partir des TransformerFactory, qui offrent toute une palette de possibilités. Voici un exemple aussi simple et dépouillé que possible :

package com.diaam.xmlfr.faqsax;

import java.io.File;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;


public class GoTransfo
{
  // arg1 : XML
  // arg2 : XSLT
  // sortie : sortie standard
  public static void main(String[] args) throws Exception
  {
    TransformerFactory fabrique;
    StreamSource xml;
    StreamSource xslt;
    StreamResult dest;
    Transformer transformation;
    
    fabrique = TransformerFactory.newInstance();
    xml = new StreamSource(new File(args[0]));
    xslt = new StreamSource(new File(args[1]));
    transformation = fabrique.newTransformer(xslt);
    dest = new StreamResult(System.out);
    transformation.transform(xml, dest);
  }
}

Il y a des noeuds composés uniquement d'espaces blancs ! Je veux les supprimer !

Voici la feuille de style qui vous sortira d'affaire :

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="text()[normalize-space()='']">
  <xsl:text> </xsl:text>
</xsl:template>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
... 

Divers

Que d'encodings, que d'encodings, que d'encodings !

Surmontez la montée du flot grâce à la liste des codes compris par Java : Supported Endodings, et en vous aidant de l'éditeur jEdit.

... et pourtant, certains caractères semblent être refusés par les parsers, alors que je les ai mis dans une section CDATA. Que faire ?

Il n'est pas permis de placer dans un document XML les caractères de code inférieur à #32, à part CR LF et TAB.

DERNIERE CHANCE : utilisez un codage base 64.

Je voudrais mettre une image dans mon XML et / ou / surtout des données binaires. Que faire ?

D'après la spécification XML, dans un document XML vous ne pouvez utiliser que les caractères 0x9, 0xA, 0xD, 0x20-0xd7ff, 0xe000-0xfffd, et 0x10000-0x10ffff. Elle exige également que les processeurs XML comprenne au moins les codages UTF 8 et UTF-16.

Cela signifie que les formats strictement binaires doivent être transformés en un codage acceptable.

Ceux qui veulent un paquetage tout fait pour cela peuvent utiliser Common Codec.

Ceux qui veulent approfondir peuvent se plonger dans Transfer binay data in an XML document.

Je n'ai pas trouvé de réponse à mon problème dans cette FAQ, et je ne comprends rien à l'anglais ! Que faire ?

Vous pouvez vous inscrire à une liste de discussion de xmlfr.org : xml-tech pour les questions techniques, xml-decid pour les questions décideur. Vous pouvez également participer à une communauté francophone hebergée par xmlfr : c'est tellement plus facile de parler à d'autres ! Vous trouverez diverses communautés parisiennes (parler XML dans un café à Paris, quel rêve ! ), une communauté quebequoise, et une communauté sur le web sémantique.

Vous n'aimez pas du tout xmlfr.org ?! C'est bizarre... Chacun ses goûts... il vous reste news:fr.comp.text.xml, et les forums d'entraide de developpez.com, par exemple.

Et est-ce si difficile d'apprendre l'anglais ?... Oubliez votre allergie scolaire, et mettez-vous au travail !

Copyright 2004, Hervé AGNOUX


 

Mots clés.



L'histoire de XML s'écrit en ce moment même. XMLfr vous aide à la suivre et à en dégager les tendances.


Les documents publiés sur ce site le sont sous licence "Open Content"
Conception graphique
  l.henriot  

Conception, réalisation et hébergement
Questions ou commentaires
  redacteurs@xmlfr.org