我必须使用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:
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);
}
}
如何通过stax提取属性?
答案 0 :(得分:3)
我在这里看到了3个问题:
您正在从XML检索hireday
而不是hiredate
标记;应该是:if ("hiredate".equals(reader.getLocalName()))
您正在使用XML所没有的命名空间检索各个属性。将其更改为NULL
,例如:
int yearAttr = Integer.parseInt(reader.getAttributeValue(null, "year"));
Java中的日历类考虑从0开始的月份(0表示1月份)。因此,您的价值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 }