Разбор содержимого файла xml без знания структуры файла xml

Я работаю над изучением некоторых новых технологий, использующих java для анализа файлов, а для части msot это хорошо. Тем не менее, я теряю информацию о том, как я могу проанализировать XML файл, где структура не известна при получении. Множество примеров того, как это сделать, если вы знаете структуру (getElementByTagName, похоже, путь), но никаких динамических параметров, по крайней мере, не я нашел.

Итак, версия tl; dr этого вопроса, как я могу проанализировать XML файл, где я не могу полагаться на его знание?

Ответ 1

Ну, парсинг-часть проста; как указано в комментариях, синтаксический анализатор требует только правильного XML, он не заботится о структуре. Вы можете использовать Java DocumentBuilder, чтобы получить Document:

InputStream in = new FileInputStream(...);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);

(Если вы разбираете несколько документов, вы можете повторно использовать один и тот же DocumentBuilder.)

Затем вы можете начать с элемента корневого документа и использовать знакомые методы DOM:

Element root = doc.getDocumentElement(); // perform DOM operations starting here.

Что касается его обработки, то это действительно зависит от того, что вы хотите с ним сделать, но вы можете использовать методы Node, например getFirstChild() и getNextSibling() для итерации по дочерним элементам и процесса, как вы сочтете нужным, основываясь на структуре, тегах и атрибутах.

Рассмотрим следующий пример:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilderFactory;   
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


public class XML {

    public static void main (String[] args) throws Exception {

        String xml = "<objects><circle color='red'/><circle color='green'/><rectangle>hello</rectangle><glumble/></objects>";

        // parse
        InputStream in = new ByteArrayInputStream(xml.getBytes("utf-8"));
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);

        // process
        Node objects = doc.getDocumentElement();
        for (Node object = objects.getFirstChild(); object != null; object = object.getNextSibling()) {
            if (object instanceof Element) {
                Element e = (Element)object;
                if (e.getTagName().equalsIgnoreCase("circle")) {
                    String color = e.getAttribute("color");
                    System.out.println("It a " + color + " circle!");
                } else if (e.getTagName().equalsIgnoreCase("rectangle")) {
                    String text = e.getTextContent();
                    System.out.println("It a rectangle that says \"" + text + "\".");
                } else {
                    System.out.println("I don't know what a " + e.getTagName() + " is for.");
                }
            }
        }

    }

}

Входящий XML-документ (с жестким кодом):

<objects>
    <circle color='red'/>
    <circle color='green'/>
    <rectangle>hello</rectangle>
    <glumble/>
</objects>

Вывод:

It a red circle!
It a green circle!
It a rectangle that says "hello".
I don't know what a glumble is for.