Подтвердить что ты не робот

Получите внутренний XML node как String в Java DOM

У меня есть XML org.w3c.dom.Node, который выглядит следующим образом:

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

Как получить часть <br /><strong>foo</strong> bar как строку?

4b9b3361

Ответ 1

Нет простого метода для org.w3c.dom.Node для этого. getTextContent() передает текст каждого дочернего элемента node вместе. getNodeValue() предоставит вам текст текущего node, если он является атрибутом, CDATA или текстом node. Таким образом, вам потребуется сериализовать node, используя комбинацию getChildNodes(), getNodeName() и getNodeValue() для построения строки.

Вы также можете сделать это с помощью одной из существующих XML-сериализационных библиотек. Существует XStream или даже JAXB. Это обсуждается в Сериализация XML в Java?

Ответ 2

Такая же проблема. Чтобы решить эту проблему, я написал эту вспомогательную функцию:

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(); 
}

Ответ 3

Если вы используете jOOX, вы можете обернуть свой node в jquery-like и просто назовите toString() на нем:

$(node).toString();

Он использует внутри себя идентификатор-трансформатор, например:

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();

Ответ 4

Продолжая ответ Andrey M, мне пришлось слегка изменить код, чтобы получить полный документ DOM. Если вы просто используете

 NodeList childNodes = node.getChildNodes();

Он не включал в себя корневой элемент для меня. Чтобы включить корневой элемент (и получить полный .xml-документ), я использовал:

 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(); 
 }

Ответ 5

Если вы не хотите обращаться к внешним библиотекам, может понадобиться следующее решение. Если у вас есть node "", и вы хотите извлечь дочерний элемент родительского элемента, выполните следующие действия:

    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();

Ответ 6

У меня возникла проблема с последним ответом, что метод nodeToStream() 'undefined; поэтому, моя версия здесь:

    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;
}

Ответ 7

Основываясь на решении Lukas Eder, мы можем извлечь innerXml, как в .NET, как показано ниже

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;               
}

Пример:

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>"

Ответ 8

Вот альтернативное решение для извлечения содержимого org.w3c.dom.Node. Это решение работает также, если содержимое node не содержит тегов 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;
}