使用SAX Parser解析UTF-8 XML文件时出现问题

时间:2011-07-20 20:18:31

标签: java xml saxparser

我正在尝试解析我制作的XML文件并从中提取信息。我基于this教程。解析连接到XML文件ok并评估第一个标记,但之后会在输出中看到崩溃。下面附有XML文件布局,Java解析代码和控制台输出。

知道为什么它不读取XML的下一个标记,如果是,我应该改变什么?


XML文件:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<filepath>/mnt/sdcard/Audio_Recorder/anonymous22242.3gp</filepath>
<filename>anonymous22242.3gp</filename>
<annotation>
    <file>anonymous22242.3gp</file>
    <timestamp>0:06</timestamp>
    <note>test1</note>
</annotation>
<annotation>
    <file>anonymous22242.3gp</file>
    <timestamp>0:09</timestamp>
    <note>lol</note>
</annotation>
<annotation>
    <file>anonymous22242.3gp</file>
    <timestamp>0:09</timestamp>
    <note>lolol</note>
</annotation>

Java文件:

private static String fileDirectory;
private final static ArrayList<String> allFileNames = new ArrayList<String>();
private final static ArrayList<String[]> allAnnotations = new ArrayList<String[]>();
private static String[] currentAnnotation = new String[3];

public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser playbackParser = factory.newSAXParser();

        DefaultHandler handler = new DefaultHandler() {

            boolean audioFullPath = false;
            boolean audioName = false;
            boolean annotationFile = false;
            boolean annotationTimestamp = false;
            boolean annotationNote = false;

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

                System.out.println("Start Element :" + qName);

                if (qName.equalsIgnoreCase("filepath")) {
                    audioFullPath = true;
                }

                if (qName.equalsIgnoreCase("filename")) {
                    audioName = true;
                }

                if (qName.equalsIgnoreCase("file")) {
                    annotationFile = true;
                }

                if (qName.equalsIgnoreCase("timestamp")) {
                    annotationTimestamp = true;
                }

                if (qName.equalsIgnoreCase("note")) {
                    annotationNote = true;
                }

            }

            public void endElement(String uri, String localName,
                    String qName) throws SAXException {

                System.out.println("End Element :" + qName);

            }

            public void characters(char ch[], int start, int length)
                    throws SAXException {

                if (audioFullPath) {
                    String filePath = new String(ch, start, length);
                    System.out.println("Full Path : " + filePath);
                    fileDirectory = filePath;
                    audioFullPath = false;
                }

                if (audioName) {
                    String fileName = new String(ch, start, length);
                    System.out.println("File Name : " + fileName);
                    allFileNames.add(fileName);
                    audioName = false;
                }

                if (annotationFile) {
                    String fileName = new String(ch, start, length);
                    currentAnnotation[0] = fileName;
                    annotationFile = false;
                }

                if (annotationTimestamp) {
                    String timestamp = new String(ch, start, length);
                    currentAnnotation[1] = timestamp;
                    annotationTimestamp = false;
                }
                if (annotationNote) {
                    String note = new String(ch, start, length);
                    currentAnnotation[2] = note;
                    annotationNote = false;
                    allAnnotations.add(currentAnnotation);
                }

            }

        };

        File file = new File(
                "c:\\Documents and Settings\\anonymous.xml");
        InputStream inputStream = new FileInputStream(file);
        Reader xmlReader = new InputStreamReader(inputStream, "UTF-8");

        InputSource xmlSource = new InputSource(xmlReader);
        xmlSource.setEncoding("UTF-8");

        playbackParser.parse(xmlSource, handler);

        System.out.println(fileDirectory);
        System.out.println(allFileNames);
        System.out.println(allAnnotations);

    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

输出:

Start Element :filepath
Full Path : /mnt/sdcard/Audio_Recorder/anonymous22242.3gp
End Element :filepath
org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$TrailingMiscDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at javax.xml.parsers.SAXParser.parse(Unknown Source)
    at main.main(main.java:131)

2 个答案:

答案 0 :(得分:5)

那不是XML。必须有一个包含所有其余元素的根元素。

答案 1 :(得分:2)

很明显,您的XML格式不正确。它必须有一个基(根)元素。我添加了<config>元素。

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<config>
    <filepath>/mnt/sdcard/Audio_Recorder/anonymous22242.3gp</filepath>
    <filename>anonymous22242.3gp</filename>
    <annotation>
        <file>anonymous22242.3gp</file>
        <timestamp>0:06</timestamp>
        <note>test1</note>
    </annotation>
    <annotation>
        <file>anonymous22242.3gp</file>
        <timestamp>0:09</timestamp>
        <note>lol</note>
    </annotation>
    <annotation>
        <file>anonymous22242.3gp</file>
        <timestamp>0:09</timestamp>
        <note>lolol</note>
    </annotation>
</config>