Как читать XML по его идентификаторам элементов?

Это мой текущий XML-файл, он дает мне диалог для разных символов, или, по крайней мере, так и должно быть. Я хочу, чтобы это работало так, чтобы я мог указать идентификатор сущности и идентификатор опции / квеста и получить вывод. И что же мне делать? Любая помощь приветствуется, большое спасибо.

<?xml version="1.0"?>
<dialoge>
<entity id="1"> <!-- questgiver -->
    <quest id="1">
        <option id="1">
            <precondition>player has not started quest</precondition>
            <output>hello there, can you kill 2 enemies for me?</output>
        </option>
        <option id="2">
            <precondition>player has completed quest and player has not...</precondition>
            <output>thankyou, have a sword for your troubles.</output>
        </option>
        <option id="3">
            <precondition>player has not finished quest</precondition>
            <output>you haven't finished yet.</output>
        </option>
        <option id="4">
            <outpur>thank you.</outpur>
        </option>
    </quest>
</entity>
<entity id="2"> <!-- villager -->
    <option id="1">
        <precondition>village is being destroyed</precondition>
        <output>our village is being destroyed, please help us!</output>
    </option>
    <option id="2">
        <precondition>village has been saved or destroyed</precondition>
        <output>we will never forget this.</output>
    </option>
    <option id="3">
        <output>hello.</output>
    </option>
</entity>
</dialoge>

Это то, что у меня сейчас есть, но это не работает. Я знаю, что это, вероятно, глупый вопрос, но я нигде не мог найти ответ в Интернете. Благодарю.

public static void read() {
    try {
        File file = new File("text.xml");
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(file);
        doc.getDocumentElement().normalize();

        System.out.println("root of xml file " + doc.getDocumentElement().getNodeName());
        NodeList nodes = doc.getElementsByTagName("entity");
        System.out.println("==========================");

        for(int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            if(node.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) node;
                        if(element.getElementsByTagName("entity").item(0).getTextContent().equals("output")) {

                }
                System.out.println("" + getValue("output", element));
            }
        }
    }catch(Exception e) {
        e.printStackTrace();
    }
}

private static String getValue(String tag, Element element) {
    NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
    Node node = (Node) nodes.item(0);
    return node.getNodeValue();
}

2 ответа

Решение

Простейшим способом может быть использование XPath...

try {
    File file = new File("text.xml");
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(file);
    doc.getDocumentElement().normalize();

    XPath xpath = XPathFactory.newInstance().newXPath();
    XPathExpression xExpress = xpath.compile("//*[@id='1']");
    NodeList nl = (NodeList) xExpress.evaluate(doc, XPathConstants.NODESET);
    System.out.println("Found " + nl.getLength() + " matches");
} catch (Exception e) {
    e.printStackTrace();
}

Запрос xpath //*[@id='1'] найдет все узлы в документе, которые имеют атрибут id со значением 1

Взгляните на WC3 XPath Tutorial и Как XPath работает для более подробной информации о XPath.

В целом, DOM проще в использовании, но требует дополнительных затрат на анализ entire XML прежде чем вы сможете начать использовать его как SAX parser анализирует XML и обнаруживает начало тега (например, <something>), то это вызывает startElement событие (фактическое название события может отличаться). прочитайте больше..

См. Java Tutorial по синтаксическому анализу XML-файла с использованием SAX.

Вот пример кода:

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class GetElementAttributesInSAXXMLParsing extends DefaultHandler {

    public static void main(String[] args) throws Exception {
        DefaultHandler handler = new GetElementAttributesInSAXXMLParsing();
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(false);
        SAXParser parser = factory.newSAXParser();
        parser.parse(new File("text.xml"), handler);    
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {

        System.out.println("Tag Name:"+qName);
        // get the number of attributes in the list
        int length = attributes.getLength();

        // process each attribute
        for (int i = 0; i < length; i++) {

            // get qualified (prefixed) name by index
            String name = attributes.getQName(i);
            System.out.println("Attribute Name:" + name);

            // get attribute's value by index.
            String value = attributes.getValue(i);
            System.out.println("Attribute Value:" + value);
        }
    }
}
Другие вопросы по тегам