4

I have to parse XML file with StAX.

I caught bunch of exceptions:

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)

here is how xml file 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>

Here is code snippet:

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

UPDATE:

Follow suggestions I changed to next:

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

And now it printed next output:

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 }

What is wrong with attributes extracting? I changed question closer to new issue.

Why does this happen? Any suggestions?

3
  • You are printing the Employee objects here: System.out.println(emp);. Try System.out.println(emp.getName());System.out.println(emp.getSalary()); etc Commented Jan 29, 2014 at 12:04
  • @PopoFibo I have toString() over written at Employee class. Commented Jan 29, 2014 at 12:06
  • Yes that is evident since it's printing the correct data. Isn't this the format you need? Commented Jan 29, 2014 at 12:07

1 Answer 1

5

Your issue is seemingly with ClassLoader#getSystemResourceAsStream(). This method would look for the resources within the classpath and if not found you would get your XMLStreamReader complaining about MalformedURL.

Options:

  1. Use FileInputStream and provide your path to your file.

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

  2. Add your xml to your eclipse classpath by - Run As -> Run Configurations -> Classpath -> Click User Entries and Click Advanced -> Add External Folder (go to the folder containing your xml)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot - I did it with next: reader = factory.createXMLStreamReader(new FileInputStream(new File(filename)));. Now it prints I'm newly Intellij user.
Now it prints - Employee { name=Carl Cracker, salary=75000.0, hireDay=null }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.