79 votes

Convertir un fragment String XML en nœud de document en Java

En Java, comment convertir un String qui représente un fragment de XML pour l'insérer dans un document XML ?

par exemple

String newNode =  "<node>value</node>"; // Convert this to XML

Ensuite, insérez ce nœud dans un org.w3c.dom.Document comme enfant d'un nœud donné ?

67voto

izb Points 12736
Element node =  DocumentBuilderFactory
    .newInstance()
    .newDocumentBuilder()
    .parse(new ByteArrayInputStream("<node>value</node>".getBytes()))
    .getDocumentElement();

33voto

McDowell Points 62645

Vous pouvez utiliser l'option import (o adopter ) pour ajouter des fragments XML :

  /**
   * @param docBuilder
   *          the parser
   * @param parent
   *          node to add fragment to
   * @param fragment
   *          a well formed XML fragment
   */
  public static void appendXmlFragment(
      DocumentBuilder docBuilder, Node parent,
      String fragment) throws IOException, SAXException {
    Document doc = parent.getOwnerDocument();
    Node fragmentNode = docBuilder.parse(
        new InputSource(new StringReader(fragment)))
        .getDocumentElement();
    fragmentNode = doc.importNode(fragmentNode, true);
    parent.appendChild(fragmentNode);
  }

15voto

Jonik Points 18905

Pour ce que ça vaut, voici une solution que j'ai trouvée en utilisant la fonction dom4j bibliothèque. (J'ai vérifié que cela fonctionne).

Lire le fragment XML dans un fichier org.dom4j.Document (note : toutes les classes XML utilisées ci-dessous sont issues de org.dom4j ; voir l'annexe) :

  String newNode = "<node>value</node>"; // Convert this to XML
  SAXReader reader = new SAXReader();
  Document newNodeDocument = reader.read(new StringReader(newNode));

Obtenez ensuite le document dans lequel le nouveau noeud est inséré, et l'élément parent (à être) de celui-ci. (Votre org.w3c.dom.Document devrait être converti en org.dom4j.Document ici). À des fins de test, j'en ai créé un comme ceci :

    Document originalDoc = 
      new SAXReader().read(new StringReader("<root><given></given></root>"));
    Element givenNode = originalDoc.getRootElement().element("given");

L'ajout d'un nouvel élément enfant est très simple :

    givenNode.add(newNodeDocument.getRootElement());

Terminé. Sortie de originalDoc donne maintenant :

<?xml version="1.0" encoding="utf-8"?>

<root>
    <given>
        <node>value</node>
    </given>
</root>

Annexe : Parce que votre question parle de org.w3c.dom.Document Voici comment convertir cette valeur en une autre. org.dom4j.Document .

// dom4j -> w3c
DOMWriter writer = new DOMWriter();
org.w3c.dom.Document w3cDoc = writer.write(dom4jDoc);

// w3c -> dom4j
DOMReader reader = new DOMReader();
Document dom4jDoc = reader.read(w3cDoc);

(Si vous avez besoin de ces deux types de Document régulièrement, il pourrait être judicieux de les placer dans des méthodes utilitaires soignées, peut-être dans une classe appelée XMLUtils ou quelque chose comme ça).

Il existe peut-être de meilleures façons de procéder, même sans bibliothèques tierces. Mais parmi les solutions présentées jusqu'à présent, c'est à mon avis la plus simple, même si vous devez effectuer les conversions dom4j <-> w3c.

Mise à jour (2011) : avant d'ajouter la dépendance dom4j à votre code, notez que c'est no un projet activement maintenu, et a quelques autres problèmes aussi . La version 2.0 améliorée est en préparation depuis longtemps, mais seule une version alpha est disponible. Vous pouvez envisager une alternative, comme XOM, à la place ; lisez-en plus dans la question liée ci-dessus.

6voto

Jonik Points 18905

Voici une autre solution, qui utilise le XOM bibliothèque qui est en concurrence avec ma réponse dom4j . (Cela fait partie de mon quête d'un bon remplacement pour le dom4j où XOM a été suggéré comme une option).

Lisez d'abord le fragment XML dans un fichier nu.xom.Document :

String newNode = "<node>value</node>"; // Convert this to XML
Document newNodeDocument = new Builder().build(newNode, "");

Ensuite, récupérez le Document et le Node sous lequel le fragment est ajouté. Encore une fois, à des fins de test, je vais créer le document à partir d'une chaîne de caractères :

Document originalDoc = new Builder().build("<root><given></given></root>", "");
Element givenNode = originalDoc.getRootElement().getFirstChildElement("given");

Maintenant, l'ajout du nœud enfant est simple, et similaire à celui de dom4j (sauf que XOM ne vous permet pas d'ajouter l'élément Root original qui appartient déjà à newNodeDocument ):

givenNode.appendChild(newNodeDocument.getRootElement().copy());

La sortie du document donne le résultat correct XML (et est remarquablement facile avec XOM : il suffit d'imprimer la chaîne retournée par originalDoc.toXML() ) :

<?xml version="1.0"?>
<root><given><node>value</node></given></root>

(Si vous souhaitez mettre en forme le XML de façon agréable (avec des indentations et des retours à la ligne), utilisez un fichier de type Serializer ; merci à Peter Štibraný de l'avoir signalé).

Donc, il est vrai que ce n'est pas très différent de la solution dom4j :) Cependant, XOM peut être un peu plus agréable à utiliser, parce que l'API est mieux documentée, et en raison de sa philosophie de conception selon laquelle il y a une façon canonique de faire chaque chose.

Annexe : Encore une fois, voici comment convertir entre org.w3c.dom.Document y nu.xom.Document . Utilisez les méthodes d'aide de l'outil XOM DOMConverter classe :

// w3c -> xom
Document xomDoc = DOMConverter.convert(w3cDoc);

// xom -> w3c
org.w3c.dom.Document w3cDoc = DOMConverter.convert(xomDoc, domImplementation);  
// You can get a DOMImplementation instance e.g. from DOMImplementationRegistry

6voto

Giordano Maestro Points 244
/**
*
* Convert a string to a Document Object
*
* @param xml The xml to convert
* @return A document Object
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
*/
public static Document string2Document(String xml) throws IOException, SAXException, ParserConfigurationException {

    if (xml == null)
    return null;

    return inputStream2Document(new ByteArrayInputStream(xml.getBytes()));

}

/**
* Convert an inputStream to a Document Object
* @param inputStream The inputstream to convert
* @return a Document Object
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
*/
public static Document inputStream2Document(InputStream inputStream) throws IOException, SAXException, ParserConfigurationException {
    DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance();
    newInstance.setNamespaceAware(true);
    Document parse = newInstance.newDocumentBuilder().parse(inputStream);
    return parse;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X