2010-07-21 6 views
21

interne d'un nœud en tant que chaîne j'ai un org.w3c.dom.Node XML qui ressemble à ceci:Get Java DOM XML

<variable name="variableName"> 
    <br /><strong>foo</strong> bar 
</variable> 

Comment puis-je obtenir la partie <br /><strong>foo</strong> bar en tant que chaîne?

Répondre

6

Il n'y a pas de méthode simple sur org.w3c.dom.Node pour cela. getTextContent() donne le texte de chaque noeud enfant concaténé ensemble. getNodeValue() vous donnera le texte du noeud courant s'il s'agit d'un attribut, d'un noeud CDATA ou d'un noeud texte. Vous devrez donc sérialiser le noeud en utilisant une combinaison de getChildNodes(), getNodeName() et getNodeValue() pour générer la chaîne.

Vous pouvez également le faire avec l'une des différentes bibliothèques de sérialisation XML existantes. Il y a XStream ou même JAXB. Ceci est discuté dans XML serialization in Java?

36

Même problème. Pour le résoudre, j'ai écrit cette fonction d'assistance:

public String innerXml(Node node) { 
    DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument().getImplementation().getFeature("LS", "3.0"); 
    LSSerializer lsSerializer = lsImpl.createLSSerializer(); 
    NodeList childNodes = node.getChildNodes(); 
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < childNodes.getLength(); i++) { 
     sb.append(lsSerializer.writeToString(childNodes.item(i))); 
    } 
    return sb.toString(); 
} 
+0

grâce, exactement ce que je avais besoin – yossi

+0

Cette méthode continue d'ajouter la balise de définition XML à l'avant de la chaîne ... est-il un moyen d'éviter que, en plus de simplement le couper après? – Nyerguds

+16

Je l'ai résolu.La solution consiste à ajouter la ligne 'lsSerializer.getDomConfig(). SetParameter (" xml-declaration ", false);' – Nyerguds

2

Si vous ne voulez pas d'avoir recours à des bibliothèques externes, la solution suivante pourrait être utile. Si vous avez un noeud « » et que vous voulez extraire le childre de l'élément parent procédez comme suit:

StringBuilder resultBuilder = new StringBuilder(); 
    // Get all children of the given parent node 
    NodeList children = parent.getChildNodes(); 
    try { 

     // Set up the output transformer 
     TransformerFactory transfac = TransformerFactory.newInstance(); 
     Transformer trans = transfac.newTransformer(); 
     trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     trans.setOutputProperty(OutputKeys.INDENT, "yes"); 
     StringWriter stringWriter = new StringWriter(); 
     StreamResult streamResult = new StreamResult(stringWriter); 

     for (int index = 0; index < children.getLength(); index++) { 
      Node child = children.item(index); 

      // Print the DOM node 
      DOMSource source = new DOMSource(child); 
      trans.transform(source, streamResult); 
      // Append child to end result 
      resultBuilder.append(stringWriter.toString()); 
     } 
    } catch (TransformerException e) { 
     //Errro handling goes here 
    } 
    return resultBuilder.toString(); 
4

Si vous utilisez jOOX, vous pouvez envelopper votre noeud dans une syntaxe jquery -comme et juste appel toString() sur elle:

$(node).toString(); 

il utilise en interne un transformateur d'identité, comme ceci:

ByteArrayOutputStream out = new ByteArrayOutputStream(); 
Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
Source source = new DOMSource(element); 
Result target = new StreamResult(out); 
transformer.transform(source, target); 
return out.toString(); 
0

bâtiment au-dessus de la solution de Lukas Eder, nous pouvons extraire InnerXml comme dans .NET comme ci-dessous

public static String innerXml(Node node,String tag){ 
     String xmlstring = toString(node); 
     xmlstring = xmlstring.replaceFirst("<[/]?"+tag+">",""); 
     return xmlstring;  

}

public static String toString(Node node){  
    String xmlString = ""; 
    Transformer transformer; 
    try { 
     transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     //transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
     StreamResult result = new StreamResult(new StringWriter()); 

     xmlString = nodeToStream(node, transformer, result); 

    } catch (TransformerConfigurationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (TransformerFactoryConfigurationError e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (TransformerException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }catch (Exception ex){ 
     ex.printStackTrace(); 
    } 

    return xmlString;    
} 

Ex:

If Node name points to xml with string representation "<Name><em>Chris</em>tian<em>Bale</em></Name>" 
String innerXml = innerXml(name,"Name"); //returns "<em>Chris</em>tian<em>Bale</em>" 
1

J'ai eu le problème avec la dernière réponse que la méthode 'nodeToStream()' est pas défini; par conséquent, ma version ici:

public static String toString(Node node){ 
    String xmlString = ""; 
    try { 
     Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     //transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 

     Source source = new DOMSource(node); 

     StringWriter sw = new StringWriter(); 
     StreamResult result = new StreamResult(sw); 

     transformer.transform(source, result); 
     xmlString = sw.toString(); 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 

    return xmlString; 
} 
3

S'étendant sur la réponse d'Andrey M, j'ai dû modifier légèrement le code pour obtenir le document DOM complet. Si vous utilisez juste le

NodeList childNodes = node.getChildNodes(); 

Il ne comprend pas l'élément racine pour moi. Pour inclure l'élément racine (et obtenir le document complet .xml) je:

public String innerXml(Node node) { 
    DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument().getImplementation().getFeature("LS", "3.0"); 
    LSSerializer lsSerializer = lsImpl.createLSSerializer(); 
    lsSerializer.getDomConfig().setParameter("xml-declaration", false); 
    StringBuilder sb = new StringBuilder(); 
    sb.append(lsSerializer.writeToString(node)); 
    return sb.toString(); 
} 
0

Voici une solution de rechange pour extraire le contenu d'un org.w3c.dom.Node. Cette solution fonctionne également si le contenu du nœud ne contient pas de balises xml:

private static String innerXml(Node node) throws TransformerFactoryConfigurationError, TransformerException { 
    StringWriter writer = new StringWriter(); 
    String xml = null; 
    Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
    transformer.transform(new DOMSource(node), new StreamResult(writer)); 
    // now remove the outer tag.... 
    xml = writer.toString(); 
    xml = xml.substring(xml.indexOf(">") + 1, xml.lastIndexOf("</")); 
    return xml; 
}