有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JAVA网StAX解析XML文件时出现异常

我必须用StAX解析XML文件

我发现了很多例外:

javax.xml.stream.XMLStreamException: java.net.MalformedURLException
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.setInputSource(XMLStreamReaderImpl.java:217)
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.<init>(XMLStreamReaderImpl.java:189)
    at com.sun.xml.internal.stream.XMLInputFactoryImpl.getXMLStreamReaderImpl(XMLInputFactoryImpl.java:262)
    at com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLStreamReader(XMLInputFactoryImpl.java:129)
    at com.epam.lab.StaxXmlParser.<init>(StAXParserDemo.java:46)
    at com.epam.lab.StAXParserDemo.main(StAXParserDemo.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.net.MalformedURLException
    at java.net.URL.<init>(URL.java:619)
    at java.net.URL.<init>(URL.java:482)
    at java.net.URL.<init>(URL.java:431)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:610)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1290)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDocumentEntity(XMLEntityManager.java:1242)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.setInputSource(XMLDocumentScannerImpl.java:257)
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.setInputSource(XMLStreamReaderImpl.java:204)

以下是xml文件loooks的用法:

<?xml version="1.0" encoding="UTF-8"?>
<staff xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="newEmployee.xsd">    
    <employee>
        <name>Carl Cracker</name>
        <salary>75000</salary>
        <hiredate year="1987" month="12" day="15" />
    </employee>
    <employee>
        <name>Harry Hacker</name>
        <salary>50000</salary>
        <hiredate year="1989" month="10" day="1" />
    </employee>
    <employee>
        <name>Tony Tester</name>
        <salary>40000</salary>
        <hiredate year="1990" month="3" day="15" />
    </employee>    
</staff>

以下是代码片段:

public class StAXParserDemo {
    public static void main(String[] args) {
        try {
            StaxXmlParser staxXmlParser = new StaxXmlParser(EMPLOYEE_XML.getFilename());
            List<Employee> employees = staxXmlParser.parseEmployee();
            for (Employee emp : employees) {
                System.out.println(emp);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }    
    }
}

class StaxXmlParser {

    private List<Employee> employeeList;
    private Employee currentEmployee;
    private String tagContent;
    private XMLStreamReader reader;

    public StaxXmlParser(String filename) {
        employeeList = null;
        currentEmployee = null;
        tagContent = null;

        try {
            XMLInputFactory factory = XMLInputFactory.newFactory();
            reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(filename));
            parseEmployee();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
    }

    public List<Employee> parseEmployee() throws XMLStreamException {
        while (reader.hasNext()) {
            int event = reader.next();

            switch (event) {
                case XMLStreamConstants.START_ELEMENT:
                    if ("employee".equals(reader.getLocalName())) {
                        currentEmployee = new Employee();
                    }
                    if ("staff".equals(reader.getLocalName())) {
                        employeeList = new ArrayList<>();
                    }
                    if ("hireday".equals(reader.getLocalName())) {
                        int yearAttr = Integer.parseInt(reader.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "year"));
                        int monthAttr = Integer.parseInt(reader.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "month"));
                        int dayAttr = Integer.parseInt(reader.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "day"));

                        currentEmployee.setHireDay(yearAttr, monthAttr, dayAttr);
                    }
                    break;

                case XMLStreamConstants.CHARACTERS:
                    tagContent = reader.getText().trim();
                    break;

                case XMLStreamConstants.END_ELEMENT:
                    switch (reader.getLocalName()) {
                        case "employee":
                            employeeList.add(currentEmployee);
                            break;
                        case "name":
                            currentEmployee.setName(tagContent);
                            break;
                        case "salary":
                            currentEmployee.setSalary(Double.parseDouble(tagContent));
                            break;
                    }
            }
        }
        return employeeList;
    }
}

更新:

遵循我改为下一步的建议:

reader = factory.createXMLStreamReader(new FileInputStream(new File(filename)));

现在它打印了下一个输出:

Employee { name=Carl Cracker, salary=75000.0, hireDay=null }
Employee { name=Harry Hacker, salary=50000.0, hireDay=null }
Employee { name=Tony Tester, salary=40000.0, hireDay=null }

属性提取有什么问题?我把问题改得更接近新问题

为什么会这样?有什么建议吗


共 (1) 个答案

  1. # 1 楼答案

    你的问题似乎与ClassLoader#getSystemResourceAsStream()有关。这个方法会在类路径中寻找资源,如果找不到,你会得到你的XMLStreamReader抱怨格式错误

    选项:

    1. 使用FileInputStream并提供文件的路径

      reader = factory.createXMLStreamReader(new FileInputStream(PATH_TO_XML));

    2. 通过-Run As->;将xml添加到eclipse classpathRun Configurations->Classpath->;单击User Entries,然后单击Advanced->Add External Folder(转到包含xml的文件夹)