質問

I am trying to create a Java program that finds the element (I am new to XML and don't understand the jargon. Is it even called an element?!?) whose value is highest and returns the element which surrounds it. Here is an example of the code:

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

It would find which "output" has the most "hits" and return the value it contains (EX. HELLO). i am trying to use stAX but it you know of a better way to do this using something different, go right ahead!

EDIT Here is the requested full code:

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

    }
}
役に立ちましたか?

解決

You could just use the java XML DOM classes to do this straightforwardly by passing over all the 'output' elements and recording which has the greatest 'hits' attribute. Say you have converted the XML to a DOM Document object 'doc', then you pass it to a method like this (returns null if there are no 'output' elements or if there are no non-zero hit attributes):

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

This would only be appropriate if the XML document is not very large, as the DOM parser will load the whole of the XML tree into memory before it can be traversed. The parsed XML tree will typically take up 5 to 10 times more space than the XML in a file. So, if your XML file is larger than a few MB, you should use a SAX or StAX parser instead.

For StAX parsing this type of information, say you have an XMLStreamReader called 'reader', then the following snippet would work (though you should probably include some error-handling capability):

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

Edit re: updated code:

I think the problem is that in your code 'reader' is an XMLEventReader (well, the reason why it would not compile). But in 'analyze' you call methods on it that are from XMLStreamReader. Just make sure you use an XMLStreamReader to carry out the operations in the method 'analyze'.

他のヒント

I'd suggest using DOM and XPATH to solve this in the simples way.

Both of these should provide with some nice ideas on how this can be done: How to find the max attribute from an XML document using Xpath 1.0

How to read XML using XPath in Java

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top