Accueil > Questions fréquemment posées concernant JDOM

Questions fréquemment posées concernant JDOM

Article original écrit par Jason Hunter et Rolf Lear et accessible ici.
Traduction par , publiée le 20 novembre 2013.
Licence : Cette traduction est mise à disposition sous un contrat Creative Commons Creative Commons License

Qu'est-ce que JDOM?

JDOM est tout simplement la représentation Java d'un document XML. JDOM fournit une façon de représenter ce document pour une lecture une manipulation et une écriture facile et efficace. Il dispose d'une API simple, est léger et rapide, et est optimisé pour le programmeur Java. C'est une alternative aux API DOM et SAX, bien qu'il s'intègre bien avec DOM et SAX.

Qu'est-ce que JDOM n'est pas?

JDOM n'est pas un wrapper pour le DOM du W3C, ou pour une autre version de DOM. JDOM est un "modèle d'objet de document" basé sur Java pour les fichiers XML. JDOM a le même but que DOM, mais est plus facile à utiliser.

JDOM n'est pas un analyseur XML, comme Xerces ou Crimson. C'est un modèle objet de document qui utilise des analyseurs XML pour créer des documents. La classe SAXBuilder de JDOM par exemple utilise les événements SAX générés par un analyseur XML pour construire un arbre JDOM. L'analyseur XML utilisé par défaut par JDOM est le analyseur JAXP, mais JDOM peut utiliser presque n'importe quel analyseur.

Est-ce que JDOM est un acronyme?

Non. Tout comme JDBC n'est pas officiellement un acronyme, JDOM n'en est pas un non plus. Cela garantit que nous respectons les politiques des marques de Sun comme expliqué au http://www.sun.com/policies/trademarks .

Quelle est la licence de JDOM?

JDOM est disponible sous une licence open source Apache-style, avec la clause de reconnaissance retirée. Cette licence est parmi les licences les moins restrictives, ce qui permet aux développeurs d'utiliser JDOM en créant de nouveaux produits sans les obliger à publier leurs propres produits en open source. C'est le modèle de licence utilisé par le Projet Apache, qui a créé le serveur Apache. La licence est disponible en haut de chaque fichier source et dans le fichier LICENSE.txt à la racine de la distribution.

Où puis-je télécharger JDOM?

JDOM est disponible au format binaire et code source depuis le site http://www.jdom.org .

JDOM est également disponible en maven central dans le groupe «org.jdom 'avec le JDOM ID d'artefact pour JDOM 1.x (et certaines versions antérieures 2.x): JDOM Artefacts 1.x sur maven , ou avec le JDOM2 d'identification des artefacts pour JDOM 2.x: JDOM Artefacts 2.x sur maven

Le référentiel de code source complet est maintenu sur GitHub .

Quel artefact Maven dois-je utiliser?

Toutes les versions de JDOM sont disponibles dans les artefacts 'jdom' et 'jdom2' dans le groupe org.jdom sur Maven . Les artefacts Maven sont en désordre pour les premières versions 2.x de JDOM apparaissant dans les artefacts 'jdom', et aussi les versions 2.x dans l'artefact 'jdom2'. Maven ne permet pas de corrgier ces erreurs, donc les utilisateurs maven doivent juste jongler avec ça.

Si votre projet nécessite à la fois JDOM 1.x et 2.x, vous pouvez également utiliser les artefcats 'jdom-legacy' version 1.1.3 (ou une version 1.x ultérieure).

Quelle est la philosophie de JDOM?

JDOM a été et continuera d'être développé avec cette philosophie:

  • JDOM doit être facile pour les programmeurs Java.
  • JDOM doit permettre la modification simple et efficace d'un document.
  • JDOM doit cacher la complexité du XML dans la mesure du possible, tout en restant fidèle à la spécification XML.
  • JDOM doit s'intégrer avec DOM et SAX.
  • JDOM doit être léger et rapide.
  • JDOM devrait résoudre 80% (ou plus) de problèmes Java/XML avec 20% (ou moins) d'effort

Pourquoi l'API JDOM est définie en termes de classes plutôt qu'en terme d'interfaces?

Cette question a été discutée à plusieurs reprises sur la liste de diffusion JDOM, avec plusieurs personnes des deux côtés. En général, beaucoup de gens pensent qu'une API basée sur les classes est meilleure lorsque le sous-classement n'est pas nécessaire, tandis qu'une interface API basée sur des interfaces est préférable lorsqu'un sous-classement est nécessaire. Toutefois, chaque système peut être utilisé dans les deux cas.

Jason Hunter résume les arguments contre une API basée sur les interfaces pour JDOM:

Avec des interfaces tout devient une usine, des éléments doivent être «importés» dans les nouveaux documents au lieu d'être simplement ajoutés, des fonctionnalités telles que la sérialisation à long terme ne peut être garantie, et la liste continue.

En fait nous avons commencé avec des interfaces. Lors de notre examen pré-version à certains membres nous avons reçu plusieurs commentaires selon lesquels nous devrions essayer les classes. Nous l'avons fait, et la conception a été bien meilleure.

Pensez à l'analogie avec java.io.File Il y a une raison pour laquelle nous écrivons:

File parent = new File(filepath);
File child = new File(parent, "aaa.txt");

plutôt que

FileSystem fs = FileSystem.getDefaultFileSystem();
File parent = fs.getFile(filepath);
File child = fs.getFile(parent, "aaa.txt");

Le premier est tout simplement plus facile et plus agréable à traiter.

Un autre point à garder à l'esprit que tout ce qui peut être fait avec les interfaces peut être fait avec le sous-classement - le seul inconvénient est peut-être les variables inutilisées dans la classe de base.

Pour référence, la dernière discussion sur ce sujet dans la liste de diffusion a commencé le 30 novembre 2000 avec «Interfaces», et a continué avec «Interface-based JDOM" et "Announce: JDOMPlus". Il serait utile d'examiner cette discussion avant de relancer ce sujet sur la liste de diffusion.

Comment JDOM travaille avec DOM et SAX?

JDOM documents peuvent être construits à partir de fichiers XML, des arbres DOM, SAX événements, ou toute autre source. Les documents JDOM peuvent être convertis en fichiers XML, en arbres DOM, en évènements SAX, ou toute autre destination. Cette capacité s'avère utile, par exemple, lors de l'intégration avec un programme qui prévoit des événements SAX. JDOM peut analyser un fichier XML, permettant au développeur de manipuler facilement et efficacement le document, puis déclencher des événements SAX directement depuis le deuxième programme - aucune conversion vers un format sérialisé n'est nécessaire.

JDOM a été conçu pour la généricité?

JDOM a été conçu avant la généricité, mais JDOM 2.x a repris la conception éprouvée de JDOM 1.x et l'a étendue pour utiliser la généricité lorsque cela est possible. Plus précisément, toutes les opérations basées sur les Collections exigent des entrées correctement typées, et renvoient des résultats correctement typés. En outre, JDOM 2.x utilisent d'autres fonctionnalités de Java 5 comme varargs, et les types de retour covariants.

Généricité: Element.getAttributes() renvoieList<Attribute>, Element.getChildren() renvoie List<Element>, ...

Types de retour covariants: Element.clone() renvoie Element, Text.detach() renvoie Text, ...

J'ai essayé d'utiliser JDOM et j'ai un message d'erreur comme celui-ci:

java.lang.NoSuchMethodError
    ou
java.lang.NoClassDefFoundError: org / xml / sax / SAXNotRecognizedException

Quel est le problème?

Vous devez vous assurer que le fichier xerces.jar fourni avec JDOM est dans votre classpath avant toutes les autres classes XML, tels que celles fournies avec JAXP ou Crimson. Ces autres bibliothèques XML, ainsi que les anciennes versions d'Apache Xerces, supportent DOM Niveau 1 et SAX 1.0, mais pas DOM niveau 2 ni SAX 2.0. Le résultat est une levée d'exception. Vérifiez votre classpath, et essayez à nouveau. Si le classpath semble OK, le JAR posant problème pourrait également se cacher dans le répertoire d'extension standard du système (voir ci-après).

Que voulez-vous dire par "répertoire standard de l'extension"?

Le répertoire standard de l'extension est un répertoire contenant les fichiers JAR qui sont recherchés automatiquement par le runtime Java et le compilateur. Si vous avez installé le JDK (pas seulement le JRE), vous pouvez très bien avoir deux répertoires distincts, dont l'un est utilisé pour la compilation (généralement quelque part, comme C:\jdk1.3\jre\lib\ext) et l'autre qui est utilisé pour l'exécution de code (généralement C:\Program Files\JavaSoft\jre\1.3\lib\ext). Le mauvais fichier JAR peut poser problème dans les 2 emplacements (mais à des moments différents). En outre, le bon fichier JAR doit être dans les deux répertoires.

Comment puis-je éviter le problème DOM Niveau 1 dans Visual Age for Java?

Lorsque la fonction WTE est ajoutée à l'espace de travail, le projet «IBM XML Parser for Java» est aussi ajouté. Ce projet contient des vielles interfaces "org.w3c.*" DOM Niveau 1. JDOM s'appuie sur DOM niveau 2, et donc entre en conflit avec ce projet. La solution est de faire ce qui suit:

  1. Mettre l'administrateur comme propriétaire de l'espace de travail
  2. Créer une édition ouverte du projet 'IBM XML Parser for Java '
  3. Supprimez tous les paquets qui contiennent les interfaces org.w3c.*
  4. Appliquer une version au projet.
  5. Créer un nouveau projet avec un analyseur DOM niveau 2 comme Xerces
  6. Importer toutes les classes Xerces, y compris les nterfaces org.w3c.* (vous pouvez utiliser un projet complètement différent pour ces interfaces si vous voulez travailler avec d'autres analyseurs)
  7. Appliquer une version au projet Xerces
  8. Créez un projet JDOM et importer des classes de JDOM. Appliquer une version au projet

(Contribution de Guy Nirpaz)

Comment puis-je éviter le problème DOM Niveau 1 dans WebSphere?

WebSphere a le même problème avec les interfaces DOM niveau 1 que VAJ ci-dessus. La solution est de faire une des options suivantes:

  • Mettre le chemin de xerces.jar (ou d'autres interfaces DOM Niveau 2) dans la variable 'com.ibm.ejs.sm.adminserver.classpath' dans le fichier admin.config. Elle se trouve dans l'$ racine_was$/bin avant toutes les autres variables.
  • ou, si vous exécutez WAS avec $WAS_ROOT/bin/debug/adminserver.{bat | sh}., ajouter une ligne 'set WAS_CP=xerces.jar' (ou autres interfaces DOM niveau 2) avant que de configurer d'autres commandes WAS_CP.
  • ou ajouter JDOM au CLASSPATH du serveur d'application, en utilisant le fichier admin.cfg ou la console d'administration.

(Contribution de Guy Nirpaz)

Quelle version de JDOM fonctionne avec quel JDK?

Les versions JDOM 1.x supportent le JDK 1.2 et versions ultérieures.

Les versions JDOM 2.x supportent le JDK 1.5 et versions ultérieures.

Y a-t-il des chiffres sur les performances?

Le processus de développement de JDOM 2.x inclus des repères pour suivre les changements de performance. Il y a des chiffres comparant différentes versions de JDOM 2.x ainsi que des chiffres comparant les performances de JDOM sur différentes versions de JDK .

Dennis Sosnoski a executé dans le passé des test de performance. En général, les modèles d'objets XML sont proches.

Comment intégrer JDOM avec XSLT?

Il ya plusieurs façons de faire des transformations XSL avec JDOM. La façon la plus simple consiste à utiliser l'interface standard JAXP Transformer et les classes JDOMSource/JDOMResult que l'on peut trouver dans le paquet org.jdom2.transform. Vous pouvez consulter l'exemple nommé XSLTransform.

Y a-t-il un support de XPath dans JDOM?

Oui! Il est entièrement intégré dans org.jdom2.xpath depuis la Beta 9, basé sur Jaxen .

Quelles caractéristiques de XML ne sont pas entièrement prises en charge par JDOM?

Aucune à notre connaissance.

Est ce que JDOM est un programme à fil sécurisé (thread safe)?

L'API de base n'est intentionnellement pas thread-safe. En d'autres termes, il n'y a pas de blocs synchronisés au sein de org.jdom. Cette décision est logique parce que nous nous attendons à des cas d'utilisation de JDOM tels que:

  • Un seul thread lit un flux XML en JDOM et regarde en lecture seule
  • Un seul thread lit un flux XML en JDOM et le modifie
  • Un seul thread lit un flux XML en JDOM et le rend disponible à un runtime du système pour un accès en lecture seule

Le cas d'utilisation où un «fil simple lit un flux XML en JDOM et l'expose à plusieurs threads pour modifier son contenu" est assez rare. Dans ce cas, JDOM peut encore être fait thread-safe, mais le développeur doit simplement effectuer sa propre synchronisation, peut-être avec une synchronisation sur l'instance du document.

D'un autre coté, il y a certaines fonctions qui nécessitent que des parties «opérationnelles» de JDOM soient thread safe:

  • org.jdom2.Namespace.getNamespace () est sûr
  • Toutes les classes type factory sont sûres (XPathFactory, ...)

Pourquoi equals() fait seulement une vérification du type ==?

En JDOM deux objets de contenu ne sont égaux que si ils sont exactement le même objet. Cela permet à un appel comme list.remove(elem) de retirer seulement l'élément exact passé,et pas un autre élément équivalent. C'est une distinction très importante. Faire un vrai equals () sur un élément exigerait de parcourir récursivement l'arbre vers les feuilles, et en général, nous pensons qu'il est peu probable que vous ayez envie de savoir si cet élément et tous ses enfants soient équivalents à un autre. Si vous voulez vraiment le faire, vous pouvez écrire votre propre code de comparaison qui vérifie seulement ce que vous voulez vérifier (peut-être uniquement le nom/namespace) au lieu de faire une récursion complète.

Pourquoi equals() est déclarée comme final?

Les méthodes equals() sont définitives pour JDOM classes de contenu de sorte qu'un sous-classe ne peut pas briser le comportement == qui est nécessaire pour les appels comme list.remove (élémentaire) fonctionne comme prévu. De même, le hashCode () sont également finales (pour préserver le contrat est égal / hashCode).

Comment puis-je construire un document à partir d'une chaîne de caractères?

Vous pouvez utiliser les appels bibliothèque Java standard IO . Encapsulez la String avec un StringReader et passer le lecteur à SAXBuilder:

Document doc = builder.build(new StringReader(xml));

Comment puis-je supprimer un élément ou un autre contenu?

Utilisez les méthodes sur la List renvoyée par getChildren () ou getContent (). JDOM n'a pas besoin de méthodes spéciales car les méthodes existent déjà dans la List. Par exemple, pour supprimer un élément d'une liste d'enfants:

List children = parent.getChildren();
children.remove(element); // supprimer un efant donné
children.remove(0);       // supprimer le premier enfant

D'autres méthodes sur List offrent des options pour éliminer tous les enfants, ajouter un enfant à un endroit donné, et ainsi de suite.

Si vous avez un élément particulier ou tout autre contenu que vous souhaitez supprimer de son parent, vous pouvez détacher le contenu avec la méthode Content.detach().

Comment puis-je déplacer un élément d'un endroit à un autre?

Il n'est pas nécessaire d'"importer" un nœud comme c'est le cas avec DOM. Il suffit de retirer l'élément de son emplacement actuel, puis ajouter l'élément à sa nouvelle place. Le contenu de l'élément (y compris ses éléments enfants) seront naturellement déplacés en même temps. Vous devez supprimer l'élément avant de l'ajouter au nouvel endroit car les éléments ne peuvent avoir qu'un seul parent renvoyé par la méthode getParent().

newParent.addContent(elt.detach());

Comment puis-je copier un élément d'un endroit à un autre?

Il n'est pas nécessaire d'"importer" un nœud comme c'est le cas avec DOM. Il suffit de cloner l'élément en cours et d'ajouter son clone à sa nouvelle place. Vous devez cloner l'élément avant de l'ajouter à son nouveau lieu car les éléments ne peuvent avoir un seul parent renvoyé par la méthode getParent().

newParent.addContent(elt.clone());

Est-ce que le nom d'un élément ou d'un attribut peut contenir le caractère deux-points?

La spécification XML 1.0 se réserve expressément le caractère deux-points (:) pour l'utilisation des espaces de noms XML. Aucune autre utilisation n'est compatible avec XML 1.0. Par conséquent JDOM ne vous permet pas de créer des noms d'éléments et d'attributs qui contiennent des deux-points, sauf lors de l'utilisation des espaces de noms. En outre, en raison de la façon dont les espaces de noms sont mis en œuvre dans JDOM, vous ne pouvez pas simplement créer un élément ou un attribut avec un nom qualifié comme svg:titre. Vous ne pouvez pas faire ceci:

Element e = new Element("svg:title");

Au lieu de cela, vous devez diviser les deux parties en un espace de noms et un nom local. C'est la façon propre à JDOM de créer un élément dans un espace de noms:

Element e = 
  new Element("title", "svg", "http://www.w3.org/2000/svg");

Le premier argument est le nom local. Le second argument est le préfixe. Le troisième argument est l'URI de l'espace de noms.

Si vous voulez créer des attributs xml:lang et xml:space:

Element e = 
  new Element("lang", Namespace.XML_NAMESPACE);

Pourquoi ai-je besoin de passer un espace de noms à GetChild(), lorsque l'élément enfant que je cherche n'a aucun espace de noms?

Plus précisément, pour ce fragment XML:

<x>
  <y xmlns="http://foo.com">
    <z />
  </y>
</x>

Vous devez utiliser le code comme ceci:

Namespace ns = Namespace.getNamespace("http://foo.com");
Element y = x.getChild("y", ns);
Element z = y.getChild("z", ns);

 

Si je ne remplis pas l'espace de noms lors du second appel à GetChild(), elle renvoie null. Pourquoi? Pourquoi?

JDOM travaille sur l'arborescence XML en mémoire logique et non la représentation textuelle sur disque. Bien que l'élément z n'a pas de déclaration d'espace de noms, il possède un espace de noms - celui hérité de son parent, qui déclare un espace de noms par défaut (associé à l'URI http://foo.com).

Conformément à la spécification des espaces de nommage, le fragment XML suivant est identique dans un sens au précédent:

<x>
  <y xmlns="http://foo.com">
    <z xmlns="http://foo.com" />
  </y>
</x>

La façon dont l'API JDOM gère les espaces de noms signifie que vous pouvez écrire du code qui fonctionne pour les deux exemples. Sinon, vous auriez besoin d'avoir du code qui vérifie chaque cas séparément.

De même, si vous construisez (au lieu de lire) du XML dans le premier exemple ci-dessus, vous auriez besoin d'écrire le code comme ceci:

Namespace ns = Namespace.getNamespace("http://foo.com");
Element y = new Element("y", ns);
x.addContent(y);
Element z = new Element("z", ns);
y.addContent(z);
Si vous avez oublié l'instance Namespace pour le constructeur de l'élément z, vous auriez eu l'arbre suivant en mémoire:
<x>
  <y xmlns="http://foo.com">
    <z xmlns="" />
  </y>
</z>

Pourquoi toutes les nouvelles lignes apparaissent comme \n, même sur Windows?

Conformément à l'article 2.11 de la recommandation XML, 2ème édition:

Pour simplifier les tâches des applications, un processeur XML doit normaliser les sauts de ligne dans les entités analysées #xA soit par la traduction de la séquence de deux caractères #xD #xA et tout #xD qui n'est pas suivi par #xA à #xA avant de commencer à parser, ou en utilisant une autre méthode telle que les caractères passés à l'application soient les mêmes que si cette transformation avait été faite.

En d'autres termes, c'est exactement ce qui est censé se produire.

Certaines entrées XML peuvent échapper à le caractère \r retour chariot par &#xD et l'analyseur XML traduira cela par un vrai caractère \r dans votre texte JDOM. Lorsque ce texte sera de nouveau utilisé en sortie, il sera ré-échappé par &#xD;.

Pourquoi setText("&#160;") ne fait pas ce que je veux?

Quand vous passez une chaîne dans une méthode comme setText () JDOM suppose que c'est juste une chaîne et non un fragment XML. Par exemple, lorsque vous appelez:

element.setText("&#160;")

JDOM suppose que vous souhaitez définir le contenu par la chaîne contenant six caractères & # 1 6 0 ;. Il n'analyse pas le contenu pour essayer de retrouver du XML. Ainsi, lorsque vous exportez le texte en utilisant XMLOutputter il va naturellement échapper l'esperluette et produira &amp;#160;. La solution est de passer des caractères Unicode à la méthode setText() ou si vous avez des données de texte que vous souhaitez qu'elels soient interprétée comme XML, passer à travers un analyseur XML avant de les passer dans JDOM. C'est ce que les classes SAXBuilder et DOMBuilder font.

Lorsque j'utilise un débogueur IDE pourquoi je vois des ArrayIndexOutOfBoundsException?

Certains analyseurs (Xerces inclus) utilisent cette exception dans le cadre de leur procédure d'utilisation standard, en déclenchant et gérant l'exception en interne. Aucun code en dehors de la bibliothèque n'est censé le voir. Cependant, les débogueurs IDE sont souvent configurés pour signaler toutes les exceptions levées, et donc ils montrent cette exception. Ce problème peut donc être ignoré en toute sécurité.

Comment puis-je ajouter une instruction ou un commentaire avant l'élément racine?

Vous devez accéder au contenu d'un document comme une List. Soit obtenir la liste et ajouter du contenu à sa tête, soit définir la liste des contenus explicitement.

doc.getContent().add(0, pi);
ou
doc.setContent(listOfContent);

Comment puis-je éviter d'obtenir une erreur OutOfMemoryError?

La plupart des machines virtuelles ont une option pour augmenter la taille maximale du tas (heap size), qui est la quantité maximale de mémoire que la machine virtuelle Java peut utiliser pour ses objets. Vous pouvez définir la taille initiale du tas à 32 Mo et la taille maximale du tas à 64 Mo avec la commande suivante:

java -Xms32m -Xmx64m SomeClass

Si vous n'avez pas besoin de tout le document en mémoire, regardez le paquet org.jdom.contrib.input.scanner du module JDOM-contrib qui vous permet de construire une partie d'un document correspondant à une expression XPath.

Pourquoi mon encodage du fichier sur la sortie ne correspond pas au codage à l'entrée?

Le codage de caractères par défaut utilisé par XMLOutputter est UTF-8, un codage à longueur variable qui peut représenter tous les caractères Unicode. Ceci peut être modifié avec un appel à format.setEncoding () sur l'objet Format passé à XMLOutputter. Ce serait bien si XMLOutputter puisse utiliser par défaut l'encodage original du fichier, mais malheureusement les analyseurs n'indiquent pas le codage d'origine. Vous devez le définir en codant.

Ce problème affecte le plus souvent les personnes avec des documents au format ISO-8859-1 (Latin-1) encodage commun qui utilisent des caractères comme ñ mais qui ne sont pas familiers avec les encodages. Le point à retenir est qu'avec ces documents vous devez définir l'encodage de sortie à la norme ISO-8859-1, autrement les caractères dans la plage 128-255 seront encodés à l'aide d'un double octet en UTF-8 au lieu de l'encodage sur un octet de ISO-8859-1.

Pourquoi passer un document à travers une socket bloque parfois l'analyseur?

Le problème est que plusieurs analyseurs XML ferment le flux d'entrée lorsqu'ils lisent EOF (-1). C'est le cas avec Xerces, qui est l'analyseur par défaut de JDOM. C'est aussi le cas avec Crimson. Malheureusement, la fermeture d'une SocketInputStream ferme la SocketImpl sous-jacente, en définissant le descripteur de fichier à NULL. Le flux de sortie du socket n'est plus utilisable après cela, et votre application ne pourra pas envoyer une réponse. Pour contourner le problème, protéger le flux d'entrée de votre socket avec une enveloppe InputStream qui ne ferme pas le flux sous-jacent (remplacer la méthode close()), ou lire tout dans une mémoire tampon avant de passer au constructeur de JDOM:

byte[] buf = new byte[length];
new DataInputStream(inputStream).readFully(buf);
InputStream in = new ByteArrayInputStream(buf);
(Merci à Joseph Bowbeer)

Comment puis-je empêcher la DTD de se charger? ême lorsque je désactive la validation l'analyseur tente de charger le fichier DTD.

Même lorsque la validation est désactivée un analyseur XML va par défaut charger le fichier DTD externe pour analyser la DTD afin d'y trouver les déclarations d'entités externes. Xerces a une fonction pour désactiver ce comportement appelé «http://apache.org/xml/features/nonvalidating/load-external-dtd" et si vous savez vous utilisez Xerces vous pouvez configurer cette fonctionnalité au moment de l'appel au constructeur.

builder.setFeature(
  "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

If you're using another parser like Crimson, your best bet is to set up an EntityResolver that resolves the DTD without actually reading the separate file.

import org.xml.sax.*;
import java.io.*;
public class NoOpEntityResolver implements EntityResolver {
  public InputSource resolveEntity(String publicId, String systemId) {
    return new InputSource(new StringBufferInputStream(""));
  }
}

Ensuite, dans le constructeur ...

builder.setEntityResolver(new NoOpEntityResolver());

Il y a un inconvénient à cette approche. Toutes les entités du document seront résolues par la chaîne vide, et seront donc effacées. Si votre document comporte des entités, vous devez utiliser setExpandEntities(false) et vous assurer que l'EntityResolver supprime seulement le DOCTYPE.

Comment puis-je valider par rapport à un schéma en utilisant JDOM 2.x?

JDOM 2.x introduit un modèle simplifié pour la validation de document. org.jdom2.input.sax.XMLReaders Enum contient des membres qui mettent en place la validation pour vous.

Le code complet en JDOM 2.x ressemble à ceci:

SAXBuilder builder =
  new SAXBuilder(XMLReaders.XSDVALIDATING);
Document doc = builder.build(xml);

Comment puis-je valider par rapport à un schéma en utilisant JDOM 1.x?

JDOM 1.x ne dispose pas de son propre analyseur, il utilise des analyseurs classiques comme Xerces pour faire le gros du travail. Si vous souhaitez utiliser la validation de schéma assurez-vous de choisir un analyseur qui prend en charge les schémas. Xerces 2 est un bon choix (le télécharger depuis http://xml.apache.org ). Vous devez également utiliser le code JDOM Beta 8 ou plus.

Pour spécifier quel analyseur JDOM utilise, vous pouvez configurer de manière appropriée JAXP (vu que JDOM utilise JAXP si il est disponible, voir à la fin de cet article pour plus de détails) ou vous pouvez passer le nom de l'analyseur au constructeur SAXBuilder. Pour Xerces 2 la classe de l'analyseur est org.apache.xerces.parsers.SAXParser. Vous devez également activer la validation de l'analyseur en passant «true» lorsque vous créez un SAXBuilder.

SAXBuilder builder =
  new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);

Ensuite, vous devez dire à l'analyseur (Xerces) que vous souhaitez valider par rapport à un schéma (ou par rapport à des schémas), et transmettre les informations sur ces schémas à l'analyseur. Chaque analyseur a sa propre façon de faire. Avec Xerces vous faites cela en définissant des «features» et «properties» spéciales de l'analyseur. JDOM expose ces paramètres de l'analyseur avec les méthodes SAXBuilder setFeature() et setProperty(). Ces méthodes relais ont été ajoutées après Beta 7, c'est pourquoi vous devez utiliser Beta 8 ou plus.

Les schémas sont activés en définissant la feature "http://apache.org/xml/features/validation/schema" à true.

builder.setFeature(
  "http://apache.org/xml/features/validation/schema", true);

les emplacements de schéma sont donnés en définissant la propriété "http://apache.org/xml/properties/schema/external-schemaLocation" avec une liste de paires nom-valeur séparées par des espaces. Le «nom» est l'espace de noms auquel le schéma est associé, la «valeur» est l'emplacement du schéma pour cet espace de noms. Par exemple:

builder.setProperty(
  "http://apache.org/xml/properties/schema/external-schemaLocation",   "http://www.w3.org/2001/12/soap-envelope soap-envelope.xsd" + " " +   "http://kevinj.develop.com/weblog/weblog.xsd weblog.xsd");

L'exemple ci-dessus montre comment valider pour plusieurs schémas - pour le schéma SOAP 1.2 où l'espace de noms est http://www.w3.org/2001/12/soap-envelope et pour un schéma dont l'espace de noms est http:// kevinj.develop.com/blog/weblog.xsd. Les fichiers décrivant ces schémas sont respectivement dans les fichiers soap-envelope.xsd et weblog.xsd. Vous pouvez ajouter autant de paires nom-valeur que nécessaire. Les valeurs elles-mêmes sont des URL. Les paires nom-valeur suivent les instructions présentes dans la recommandation sur les schémas ( http://www.w3.org/TR/xmlschema-1/#schema-loc ).

Le code complet ressemble à ceci:

SAXBuilder builder =
  new SAXBuilder("org.apache.xerces.parsers.SAXParser", true);
builder.setFeature(
  "http://apache.org/xml/features/validation/schema", true);
builder.setProperty(
  "http://apache.org/xml/properties/schema/external-schemaLocation",
  "http://www.w3.org/2001/12/soap-envelope soap-envelope.xsd" + " " +
  "http://kevinj.develop.com/weblog/weblog.xsd weblog.xsd");
Document doc = builder.build(xml);

Si vous souhaitez utiliser JAXP pour sélectionner l'analyseur, vous pouvez éviter de spécifier une classe au constructeur SAXBuilder et la place définir la propriété javax.xml.parsers.SAXParserFactory" à "org.apache.xerces.jaxp.SAXParserFactoryImpl". Cela indique à JAXP d'utiliser la factory Xerces pour construire des analyseurs syntaxiques. Si vous le souhaitez, vous pouvez spécifier cette propriété en ligne de commande:

java -Djavax.xml.parsers.SAXParserFactory=
          org.apache.xerces.jaxp.SAXParserFactoryImpl ...

(Contribution de Kevin Jones)

Comment puis-je effectuer une validation en mémoire en utilisant une DTD ou un schéma?

Actuellement, vous ne pouvez pas faire cela, ni dans JDOM ni dans aucun modèle de document objet de l'API Java. Cependant, c'est quelque chose que nous aimerions que JDOM puisse faire, et nous avons un bénévole qui travaille sur cette fonctionnalité.

JDOM assure le document en mémoire est toujours bien formé. Est-ce que JDOM peut également certifier que le document en mémoire est toujours valide?

Non, c'est notre conviction selon laquelle il est préférable d'exposer un type d'appel checkValid() plutot que de tenter une vérification de la validation constante. Une de ces raisons est la performance. Une deuxième raison est que vous avez un problème de la poule et de l'œuf où par exemple un élément doit exactement avoir deux éléments enfants pour être valable, mais après l'ajout de chaque enfant le document sera dans un état temporairement invalide. Pour contourner ceci il faudrait utiliser quelque chose comme des modifications transactionnelles, et c'est beaucoup de travail supplémentaire pour peu de gain.

Pourquoi ai-je une IndexOutOfBoundsException ou ConcurrentModificationException sur une boucle?

Le code suivant lèvera une exception IndexOutOfBoundsException:

 List children = root.getChildren("foo");
 int size = children.size();
 for (int i = 0; i < size; i++) {
   Element child = (Element) children.get(i);
   child.detach();
   otherRoot.addContent(child);
 }

La raison est que la taille de la liste est pré-calculée, mais la taille est réduite de un à chaque appel de detach(), entrainant la boucle à dépasser la fin de la liste. La bonne façon de boucler est d'utiliser un Iterator. Avec un Iterator vous n'avez pas ce problème, et c'est aussi plus rapide.

Cependant, même avec un Iterator, le code suivant génère une ConcurrentModificationException:

 List children = root.getChildren("foo");
 Iterator itr = children.iterator();
 while (itr.hasNext()) {
   Element child = (Element) itr.next();
   child.detach();
   otherRoot.addContent(child);
 }

La raison en est que l'appel à detach() modifie la liste des enfants en même temps que l'itérateur parcourt la liste, et c'est une modification concurrente. La solution est d'utiliser la méthode remove() de l'itérateur au lieu d'utiliser detach():

List children = root.getChildren("foo");
 Iterator itr = children.iterator();
 while (itr.hasNext()) {
   Element child = (Element) itr.next();
   itr.remove();
   otherRoot.addContent(child);
 }

Y at-il une archive des listes de diffusion JDOM?

Oui, tous les messages sont disponibles pour une lecture sur le Web. Voici la liste des archives consultables:

Il y a d'autres archives à ces adresses:

Comment puis-je me désabonner de la liste de diffusion?

L'URL pour gérer votre appartenance à une liste (y compris l'abonnement) est inclus au bas de chaque message de la liste. C'est quelque chose comme http://www.jdom.org/mailman/options/jdom-interest/ youraddr@yourhost.com. Assurez-vous de remplacer "youraddr" avec votre adresse et "yourhost" avec votre fournisseur de messagerie. Pour la liste jdom-announce remplacer «interest» par «announce» dans l'URL.

Comment puis-je poster sur la liste de diffusion à partir de plusieurs adresses?

Pour protéger la liste du spam, seuls les membres de la liste de diffusion peuvent poster. Pour poster à partir de plusieurs comptes, abonnez-vous pour chaque compte et cocher l'option "Disable mail delivery" sur "On" pour tous les comptes supplémentaires. Vous pouvez configurer cette fonctionnalité à l'adresse indiquée dans la réponse précédente .

Puis-je poser des questions générales XML à Jason, Brett, ou Rolf?

Non, ils sont déjà assez occupés. Mais vous pouvez commander le livre de Brett Java et XML ou l'un des autres livres d'introduction à XML comme XML Bible par Elliotte Rusty Harold (l'un des membres importants de notre liste jdom-interest).

Le livre Java et XML parle de JDOM 1.0; pourquoi cette confusion?

Le livre couvre une très vieille bêta. Beaucoup de choses ont changé (pour le mieux) depuis la publication du livre. Pour connaître l'API JDOM faites confiance aux Javadocs, pas au livre. Brett était un peu optimiste lors de l'écriture du livre. Sa 2ème édition met les choses au point.

J'ai une question qui n'est pas traitée ici. Que dois-je faire?

Tout d'abord, vous devez chercher dans les archives de la liste de diffusion JDOM . Par exemple, si vous utilisez un analyseur Oracle et que vous avez une exception IllegalTargetExceptionétrange, vous pouvez rechercher «oracle IllegalTargetException" et vous trouverez un sujet traitant de cette question. Les recherches sont puissantes et rapides!

Si vous ne trouvez pas de réponse dans les archives, vous pouvez poster sur jdom-interest. Si vous pensez avoir trouvé un bug, assurez-vous que vous suivez les conseils suivants sur les rapports de bug!

Comment puis-je soumettre un rapport de bug?

Si vous pensez avoir trouvé un bogue dans JDOM, s'il vous plaît suivez cette procédure:

  1. Vérifiez les bogues connus et les bogues corrigés pour voir si c'est un problème connu.
  2. Vérifiez si le problème se produit lorsque vous utilisez la dernière version de développement (source. zip) de JDOM.
  3. Recherchez dans les archives de la liste de diffusion JDOM comme expliqué ci-dessus.
  4. Si vous ne trouvez pas la résolution avec le dernier snapshot, soit créer un problème sur GitHub ou en postant sur la liste de diffusion jdom-interest, assurez-vous que vous êtes abonné avant car seuls les abonnés peuvent poster.
  5. Dans le rapport de bogue, donner autant d'informations que possible - la trace de la pile, un exemple de code reproductible et court, le fichier XML posant problème. Assurez-vous d'indiquer la version de JDOM utilisée (version officielle ou GitHub commit).
  6. Si vous avez un patch pour corriger le bug, envoyez le en même temps que le rapport de problème. Nous adorons les patches.

Où puis-je en savoir plus?

la documentation de l'API JDOM, les diapositives de l'annonce officielle de JDOM, et d'autres ressources utiles peuvent être téléchargées ici .

Des erreurs ? Merci de me les signaler : | Accueil du site traduction.cc