2014-01-29 46 views
4

我必須用StAX解析XML文件。java.net.MalformedURLException - 用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; 
    } 
} 

UPDATE:

按照建議我改下一個:

讀卡器= factory.createXMLStreamReader(新的FileInputStream(新文件(文件名)));

而現在它印下一個輸出:

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 } 

什麼是錯的屬性提取?我更接近新問題改變了問題。

爲什麼會發生這種情況?有什麼建議麼?

+0

您正在打印Employee對象:'System.out.println(emp);'。嘗試'的System.out.println(emp.getName());的System.out.println(emp.getSalary());'等 – PopoFibo

+0

@PopoFibo我有'的toString()'在上Employee類寫的。 –

+0

是的,這是顯而易見的,因爲它正在打印正確的數據。這不是你需要的格式嗎? – PopoFibo

回答

4

你的問題似乎與ClassLoader#getSystemResourceAsStream()。這種方法會尋找類路徑中的資源,如果沒有找到,你會得到你的抱怨MalformedURL XMLStreamReader

選項:

  1. 使用FileInputStream,並提供給您的文件路徑中。 Run As - -

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

  2. 您的XML添加到Eclipse classpath>Run Configurations - >Classpath - >點擊User Entries和點擊Advanced - >Add External Folder(轉到文件夾包含您的XML)

+0

非常感謝 - 我旁邊做了它:'讀卡器= factory.createXMLStreamReader(新的FileInputStream(新文件(文件名)));'。現在它打印出我是Intellij的新用戶。 –

+0

@nazar_art它現在工作正確嗎? – PopoFibo

+0

現在它打印 - '員工{名稱=卡爾餅乾,薪水= 75000.0,hireDay = null}' –