2014-01-28 142 views
0

我必須解析xml文件與xsd驗證。我打了一個點,找不到解決辦法。從SAX當前元素提取屬性?

這裏是如何將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> 

XSD驗證:

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

    <xsd:element name="staff"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element ref="employee" maxOccurs="unbounded" minOccurs="0"/> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 

    <xsd:element name="employee"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element type="xsd:string" name="name"/> 
       <xsd:element type="xsd:int" name="salary"/> 
       <xsd:element name="hiredate"> 
        <xsd:complexType> 
         <xsd:simpleContent> 
          <xsd:extension base="xsd:string"> 
           <xsd:attribute type="xsd:short" name="year" use="optional"/> 
           <xsd:attribute type="xsd:byte" name="month" use="optional"/> 
           <xsd:attribute type="xsd:byte" name="day" use="optional"/> 
          </xsd:extension> 
         </xsd:simpleContent> 
        </xsd:complexType> 
       </xsd:element> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

xml validator檢查它。一切正確。

這裏是我的代碼片段:

public class SaxParserDemo { 
    public static void main(String[] args) { 
     Schema schema; 
     String language = XMLConstants.W3C_XML_SCHEMA_NS_URI; 
     SchemaFactory schemaFactory = SchemaFactory.newInstance(language); 

     try { 
      schema = schemaFactory.newSchema(new File(EMPLOYEE_XSD.getFilename())); // create new xml schema 
      SAXParserFactory factory = SAXParserFactory.newInstance(); 
      factory.setSchema(schema); // set schema to the factory 

      InputStream xmlInput = new FileInputStream(EMPLOYEE_XML.getFilename()); 
      SAXParser saxParser = factory.newSAXParser(); 
      SaxHandler handler = new SaxHandler(); 
      saxParser.parse(xmlInput, handler); 

      for (Employee employee : handler.employees) { 
       System.out.println(employee); 
      } 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class SaxHandler extends DefaultHandler { 

    private Stack<String> elementStack = new Stack<>(); 
    private Stack<Object> objectStack = new Stack<>(); 

    public List<Employee> employees = new ArrayList<>(); 

    @Override 
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
     this.elementStack.push(qName); 

     if ("employee".equals(qName)) { 
      Employee employee = new Employee(); 
      this.objectStack.push(employee); 
      this.employees.add(employee); 
     } 
    } 

    @Override 
    public void endElement(String uri, String localName, String qName) throws SAXException { 
     this.elementStack.pop(); 

     if ("employee".equals(qName)) { 
      Object objects = this.objectStack.pop(); 
     } 
    } 

    @Override 
    public void characters(char[] ch, int start, int length) throws SAXException { 
     String value = new String(ch, start, length).trim(); 
     if (value.length() == 0) return;  // skip white space 

     if ("name".equals(currentElement())) { 
      Employee employee = (Employee) this.objectStack.peek(); 
      employee.setName(value); 
     } else if ("salary".equals(currentElement()) && "employee".equals(currentParrentElement())) { 
      Employee employee = new Employee(); 
      employee.setSalary(Double.parseDouble(value)); 
     } else if ("hiredate".equals(currentElement()) && "employee".equals(currentParrentElement())) { 
      Employee employee = new Employee(); 
      // I stuck here 
//   employee.setHireDay(); 
     } 
    } 

    private String currentElement() { 
     return this.elementStack.peek(); 
    } 

    private String currentParrentElement() { 
     if (this.elementStack.size() < 2) return null; 
     return this.elementStack.get(this.elementStack.size() - 2); 
    } 

} 

我要提取元素屬性數據。我無法弄清楚如何實現它。我第一次使用SAX。有什麼建議麼?

員工類有hireday兩個設置方法:

setHireDay(日期hireDay)

setHireDay(INT年,月整型,日整型)

如何解決這個問題?

回答

0

像DIS

import java.io.File; 
import java.io.FileInputStream; 
import java.io.InputStream; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import java.util.Stack; 

import javax.xml.XMLConstants; 
import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

public class SaxParserDemo { 
    public static void main(String[] args) { 
     Schema schema; 
     String language = XMLConstants.W3C_XML_SCHEMA_NS_URI; 
     SchemaFactory schemaFactory = SchemaFactory.newInstance(language); 

     try { 
      schema = schemaFactory.newSchema(new File("src/newEmployee.xsd")); // create new xml schema 
      SAXParserFactory factory = SAXParserFactory.newInstance(); 
      factory.setSchema(schema); // set schema to the factory 

      InputStream xmlInput = new FileInputStream("src/empl.xml"); 
      SAXParser saxParser = factory.newSAXParser(); 
      SaxHandler handler = new SaxHandler(); 
      saxParser.parse(xmlInput, handler); 

      for (Employee employee : handler.employees) { 
       System.out.println(employee.getName()); 
       System.out.println(employee.getSalary()); 
       System.out.println(employee.getHireDate()); 
      } 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class SaxHandler extends DefaultHandler { 

    private Stack<String> elementStack = new Stack<String>(); 
    private Stack<Object> objectStack = new Stack<Object>(); 

    public List<Employee> employees = new ArrayList<Employee>(); 
    Employee employee=null; 
    @Override 
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 
     this.elementStack.push(qName); 

     if ("employee".equals(qName)) { 

      if(employee!=null) 
      { 
        this.employees.add(employee); 
      } 
      employee = new Employee(); 
      this.objectStack.push(employee); 

     } 
     if("hiredate".equals(qName)) 
     { 
      String yearatt=attributes.getValue("year"); 
      System.out.println(yearatt); 
      String monthatt=attributes.getValue("month"); 
      System.out.println(monthatt); 
      String dayatt=attributes.getValue("day"); 
      System.out.println(dayatt); 
      employee.setHireDay(yearatt, monthatt, dayatt) ; 
     } 
    } 

    @Override 
    public void endElement(String uri, String localName, String qName) throws SAXException { 
     this.elementStack.pop(); 

     if ("employee".equals(qName)) { 
      Object objects = this.objectStack.pop(); 
     } 
    } 

    @Override 
    public void characters(char[] ch, int start, int length) throws SAXException { 
     String value = new String(ch, start, length).trim(); 
     if (value.length() == 0) return;  // skip white space 

     if ("name".equals(currentElement())) { 
      employee = (Employee) this.objectStack.peek(); 
      employee.setName(value); 
     } else if ("salary".equals(currentElement()) && "employee".equals(currentParrentElement())) { 

      employee.setSalary(Double.parseDouble(value)); 
     } else if ("hiredate".equals(currentElement()) && "employee".equals(currentParrentElement())) { 



      // I stuck here 
//   employee.setHireDay(); 
     } 
    } 

    private String currentElement() { 
     return this.elementStack.peek(); 
    } 

    private String currentParrentElement() { 
     if (this.elementStack.size() < 2) return null; 
     return this.elementStack.get(this.elementStack.size() - 2); 
    } 

}