Как разобрать полное содержимое тега XML в java - PullRequest
2 голосов
/ 03 февраля 2020

У меня какая-то сложная XML структура данных. Структура содержит различные фрагменты, как в следующем примере:

<data>
  <content-part-1>
   <h1>Hello <strong>World</strong>. This is some text.</h1>
   <h2>.....</h2>
  </content-part1>
  ....
</data>

Интерес представляет тег h1 внутри тега «content-part-1». Я хочу получить полное содержимое тега xml 'h1'.

В java я использовал javax. xml .parsers.DocumentBuilder и попробовал что-то вроде этого:

String my_content="<h1>Hello <strong>World</strong>. This is some text.</h1>"; 
// parse h1 tag..
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader(my_content)));
Node node = doc.importNode(doc.getDocumentElement(), true);
if (node != null && node.getNodeName().equals("h1")) {
    return node.getTextContent();
}

Но метод getTextContent () вернет:

Hello World. This is some text.

Тег "strong" удаляется анализатором xml (так как это задокументированное поведение).

Мой вопрос заключается в том, как извлечь полное содержимое одного XML узла в пределах org.w3 c .dom.Document без дальнейшего анализа содержимого узла?

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

Хотя java DOM-парсер предоставляет функциональные возможности для анализа смешанного контента, в данном конкретном случае было бы удобнее использовать библиотеку Jsoup. При его использовании код для извлечения содержимого элемента h1 будет выглядеть следующим образом:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

String text = "<data>\n"
+ "  <content-part1>\n"
+ "   <h1>Hello <strong>World</strong>. This is some text.</h1>\n"
+ "   <h2></h2>\n"
+ "  </content-part1>\n"
+ "</data>";

Document doc = Jsoup.parse(text);

Elements h1Elements = doc.select("h1");

for (Element h1 : h1Elements) {
    System.out.println(h1.html());
}

В этом случае будет выведено «Hello <strong>World</strong>. This is some text.»

0 голосов
/ 03 февраля 2020

То, что вы, вероятно, хотите, - это XML генерация из некоторого подузла вашего документа. Таким образом, с незначительным изменением nodeToString из предыдущего ответа на аналогичный вопрос я могу предложить сгенерировать текст <h1>Hello <strong>World</strong>. This is some text.</h1>. Чтобы избавиться от <h1> и </h1>

package com.github.vtitov.test;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.StringReader;
import java.io.StringWriter;

import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;


public class XmlTest {

    @Test
    public void buildXml() throws Exception {
        String my_content="<h1>Hello <strong>World</strong>. This is some text.</h1>";
        // parse h1 tag..
        DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = documentBuilder.parse(new InputSource(new StringReader(my_content)));
        Node node = doc.importNode(doc.getDocumentElement(), true);
        String h1Content = null;
        if (node != null && node.getNodeName().equals("h1")) {
            h1Content = nodeToString(node);
        }
        assertThat("h1", h1Content, equalTo("<h1>Hello <strong>World</strong>. This is some text.</h1>"));
    }

    private static String nodeToString(Node node) throws TransformerException {
        StringWriter sw = new StringWriter();
        Transformer t = TransformerFactory.newInstance().newTransformer();
        t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        t.setOutputProperty(OutputKeys.INDENT, "no");
        t.transform(new DOMSource(node), new StreamResult(sw));
        return sw.toString();
    }
}
, может потребоваться дополнительное усилие
...