2014-01-29 77 views
2

我必须用stax解析xml文件,而且除了一点之外,我主要做了我需要的。如何使用Stax从xml文件中提取属性值?

我的代码逻辑不提取属性在右边。我的输出看起来未来:

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 } 

下面是XML文件的内容:

<?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> 

这里是我的代码:

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(new FileInputStream(new File(filename))); 
      parseEmployee(); 
     } catch (Exception 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; 
    }  
} 

这里是Employee类的内容:

class Employee { 

    private String name; 
    private double salary; 
    private Date hireDay; 

    public Employee() {} 

    public Employee(String n, double s, int year, int month, int day) { 
     name = n; 
     salary = s; 
     GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); 
     // GregorianCalendar uses 0 for January 
     hireDay = calendar.getTime(); 
    } 

    public String getName() { 
     return name; 
    } 

    public double getSalary() { 
     return salary; 
    } 

    public Date getHireDay() { 
     return hireDay; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public void setSalary(double salary) { 
     this.salary = salary; 
    } 

    public void setHireDay(Date hireDay) { 
     this.hireDay = hireDay; 
    } 

    public void setHireDay(int year, int month, int day) { 
     GregorianCalendar calendar = new GregorianCalendar(year, month, day); 
     this.hireDay = calendar.getTime(); 
    } 

    public void raiseSalary(double byPercent) { 
     double raise = salary * byPercent/100; 
     salary += raise; 
    } 

    @Override 
    public String toString() { 
     return String.format("Employee { name=%s, salary=%s, hireDay=%s }", name, salary, hireDay); 
    } 

    @Override 
    public int hashCode() { 
     return super.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return super.equals(obj); 
    } 
} 

如何提取att由stax?

+0

你就必须按你的'Employee'类以及 – PopoFibo

+0

@ PopoFibo我更新了问题。 –

回答

3

我看到3个问题与您的代码在这里:

  1. 要检索的hireday代替hiredate从XML标签;应该是:if ("hiredate".equals(reader.getLocalName()))

  2. 您正在使用XML中没有的名称空间检索单个属性。将其更改为NULL,如:Java中

    int yearAttr = Integer.parseInt(reader.getAttributeValue(null, "year"));

  3. Calendar类认为从0(0为日)起个月。因此,你的价值12将转移到明年。您可能需要从月份值中减去1以获得所需的输出。

    currentEmployee.setHireDay(yearAttr, monthAttr - 1, dayAttr);

你修改parseEmployee()

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 ("hiredate".equals(reader.getLocalName())) { 
        int yearAttr = Integer.parseInt(reader.getAttributeValue(
          null, "year")); 
        int monthAttr = Integer.parseInt(reader.getAttributeValue(
          null, "month")); 
        int dayAttr = Integer.parseInt(reader.getAttributeValue(
          null, "day")); 

        currentEmployee 
          .setHireDay(yearAttr, monthAttr - 1, 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; 
    } 

现在你得到正确的输出:

Employee { name=Carl Cracker, salary=75000.0, hireDay=Tue Dec 15 00:00:00 IST 1987 } 
Employee { name=Harry Hacker, salary=50000.0, hireDay=Sun Oct 01 00:00:00 IST 1989 } 
Employee { name=Tony Tester, salary=40000.0, hireDay=Thu Mar 15 00:00:00 IST 1990 } 
相关问题