Возврат XML-элемента с наибольшим значением

Я пытаюсь создать программу на Java, которая находит элемент (я новичок в XML и не понимаю жаргон. Он даже называется элементом?!?), Значение которого самое высокое, и возвращает элемент, который его окружает. Вот пример кода:

<conversation input="HELLO">
    <output hits="3">
        HI MATE
    </output>
    <output hits="8">
        HELLO
    </output>
</conversation>

Он найдет, какой "выход" имеет наибольшее количество "хитов", и вернет значение, которое он содержит (например, ПРИВЕТ). я пытаюсь использовать stAX, но если вы знаете, как лучше сделать это, используя что-то другое, идите!

РЕДАКТИРОВАТЬ Вот запрашиваемый полный код:

package charles;

import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.swing.JOptionPane;
import javax.xml.stream.*;
import javax.xml.stream.events.*;

public class NewClass {

    //Memory
    static String currentResult = null;
    static int highestHits = 0;
    private static String filename = "\\Files\\Java\\Projects\\CHARLES\\src\\charles\\Memory.xml";
    static XMLEventReader reader;

    public static void main(String args[]) throws XMLStreamException, FileNotFoundException {

        try {
            filename = "\\Files\\Java\\Projects\\CHARLES\\src\\charles\\Memory.xml";
        } catch (ArrayIndexOutOfBoundsException aioobe) {
            System.exit(0);
        }
        try {
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLEventReader reader =
                    factory.createXMLEventReader(new FileReader(filename));
            while (reader.hasNext()) {
                XMLEvent e = reader.nextEvent();
                System.out.println("ID:" + e.hashCode() + "[" + e + "]");
            }
        } catch (FileNotFoundException e) {
            JOptionPane.showMessageDialog(null, "The file does not exist!" + "\nProgram is terminating.", "File Not Found", JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);
        }

    }

    private static void analyze() {
        while (reader.hasNext()) {
            int event = (int) reader.next();
            if (event == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals(input)) {
                int currentHits = Integer.parseInt(reader.getAttributeValue(0));
                if (currentHits > highestHits) {
                    highestHits = currentHits;
                    reader.next();
                    currentResult = reader.getText();
                }
            }
        }

    }
}

2 ответа

Решение

Вы можете просто использовать java XML DOM классы, чтобы сделать это прямо, пропустив все элементы "output" и записав, что имеет атрибут "наибольшие хиты". Скажем, вы преобразовали XML в объект DOM Document 'doc', а затем передаете его методу, подобному этому (возвращает ноль, если нет элементов 'output' или если нет ненулевых атрибутов попадания):

    public String getHighest(Document doc) {   
        NodeList list = doc.getElementsByTagName("output");
        String currentResult = null;
        int highestHit = 0;
        for (int i = 0; i < list.getLength(); i++) {
            int hits = Integer.parseInt(((Element) list.item(i)).getAttribute("hits"));
            if (hits > highestHit) {
                highestHit = hits;
                currentResult = list.item(i).getTextContent();
            }
         }
         return currentResult;
    }

Это будет уместно, только если документ XML не очень большой, так как анализатор DOM загрузит все дерево XML в память, прежде чем его можно будет просмотреть. Анализируемое дерево XML обычно занимает в 5-10 раз больше места, чем XML в файле. Таким образом, если ваш XML-файл больше, чем несколько МБ, вы должны использовать вместо этого парсер SAX или StAX.

Для анализа StAX этого типа информации, скажем, у вас есть XMLStreamReader с именем 'reader', тогда будет работать следующий фрагмент (хотя вам, вероятно, следует включить некоторые возможности обработки ошибок):

    int highestHits = 0;
    String currentResult = null;
    while (reader.hasNext()) {
        int event = reader.next();
        if (event == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("output")) {
            int currentHits = Integer.parseInt(reader.getAttributeValue(0));
            if (currentHits > highestHits) {
                highestHits = currentHits;
                reader.next();
                currentResult = reader.getText();
            }
        }
    }

Изменить re: обновленный код:

Я думаю, что проблема в том, что в вашем коде "читатель" - это XMLEventReader (ну, причина, по которой он не будет компилироваться). Но в "анализ" вы вызываете методы из XMLStreamReader. Просто убедитесь, что вы используете XMLStreamReader для выполнения операций в методе "анализ".

Я бы предложил использовать DOM и XPATH, чтобы решить эту проблему самым простым способом.

Оба из них должны дать некоторые хорошие идеи о том, как это можно сделать: Как найти атрибут max из документа XML с использованием Xpath 1.0

Как читать XML с использованием XPath в Java

Другие вопросы по тегам