2016-03-24 70 views
0

我有一个XML文件,我很想从SAX获取数据。一直到startElement()它出现错误,因为当我尝试获取属性值时,它们为空。为什么?Java - SAXParser和XMLReader获取null属性值

首先,我调用这个方法:负载()

public RealEstate load() { 
     RealEstate data = null; 
     try {  
      //Create a "parser factory" for creating SAX parsers 
      SAXParserFactory spfac = SAXParserFactory.newInstance(); 

      //Now use the parser factory to create a SAXParser object 
      SAXParser sp = spfac.newSAXParser(); 
      XMLReader xmlReader = sp.getXMLReader(); 

      //Create an instance of this class; it defines all the handler methods 
      SaxParserRealEstateHandler handler = new SaxParserRealEstateHandler(); 

      //assign our handler 
      xmlReader.setContentHandler(handler); 

      // Convert file to URL. 
      URL url = handler.fileToURL(new File(xmlFilename)); 

      // Parse file. 
      xmlReader.parse(url.toString()); 

      data = handler.getData(); 

     } catch (ParserConfigurationException ex) { 
      Logger.getLogger(RealStatePersistXML.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (SAXException ex) { 
      Logger.getLogger(RealStatePersistXML.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (IOException ex) { 
      Logger.getLogger(RealStatePersistXML.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     return data; 
    } 

在这里,我有方法的startElement的endElement

class SaxParserRealEstateHandler extends DefaultHandler 
    { 

     private String temp; 
     private RealEstate data; 
     private Estate estate; 
     private estateAddress address; 

     /** 
     * CONSTRUCTOR 
     */ 
     public SaxParserRealEstateHandler() 
     { 
     } 


     /** 
     * getData() 
     * This method gets the list of estates from RealEstate class. 
     * @return data list of states. Null in case of error or list not found. 
     */ 
     public RealEstate getData() 
     { 
     // RealEstate data = new RealEstate(); 
      // data.addEstate(estate); 
      // data.getEstates(); 
     // return data; 
     } 

     /* 
     * When the parser encounters plain text (not XML elements), 
     * it calls(this method, which accumulates them in a string buffer 
     */ 
     public void characters(char[] buffer, int start, int length) { 
      temp = new String(buffer, start, length); 
     } 


     /* 
     * Every time the parser encounters the beginning of a new element, 
     * it calls this method, which resets the string buffer 
     */ 
     public void startElement(String uri, String localName, String qName, Attributes attributes){ 

      switch (qName){  
       case"realState": 
        data = new RealEstate(); 
        break; 
       case"estate": 
        estate = new Estate(); 
        estate.setType(attributes.getValue("type")); 
        estate.setSurface(Double.parseDouble(attributes.getValue("surface"))); 
        //estate.setAddress(attributes.getValue("address")); 
        estate.setPrice(Integer.parseInt(attributes.getValue("price"))); 
        break;  
       case"address": 
        address = new estateAddress(); 
        address.setStreet(attributes.getValue("type")); 
        address.setNumber(Integer.parseInt(attributes.getValue("surface"))); 
        address.setFloor(Integer.parseInt(attributes.getValue("type"))); 
        address.setDoor(Integer.parseInt(attributes.getValue("surface"))); 
        break; 
       default: 
        break; 
      } 
     } 



    public void endElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 

    switch (qName){ 
     case"estate": 
      data.getEstates().add(estate);//quant ha llegit la etiqueta (</estate>) l'agreguem 
      break; 
     case"surface": 
      double surface = Double.parseDouble(temp); 
      estate.setSurface(surface); 
      break; 
     case"price": 
      double price = Double.parseDouble(temp);//tractar tema errors del parseDouble! 
      estate.setPrice(price); 
      break;  
     case"address":      
      estate.setAddress(address); 
      break;  
     case"street": 
      address.setStreet(temp); 
      break; 
     case"number": 
      int number = Integer.parseInt(temp); 
      address.setNumber(number); 
      break; 
     case"floor": 
      address.setStreet(temp); 
      break; 
     case"door": 
      address.setStreet(temp); 
      break; 
     default: 
      break; 
    } 
} 



/** fileToURL() 
* Convenience method to convert a file to a url 
* @throws Error if malformed url exception is generated 
*/ 

    public URL fileToURL(File file) 
{ 
    String path = file.getAbsolutePath(); 
    String fSep = System.getProperty("file.separator"); 
    if (fSep != null && fSep.length() == 1) 
     path = path.replace(fSep.charAt(0), '/'); 
    if (path.length() > 0 && path.charAt(0) != '/') 
     path = '/' + path; 
    try 
    { 
     return new URL("file", null, path); 
    } 
    catch (java.net.MalformedURLException e) 
    { 
     throw new Error("Unexpected MalformedURLException");//no he pogut muntar una url com deu mana 
     //retornar null 
    } 
} 
    } 

XML代码

<?xml version="1.0" encoding="UTF-8"?> 
<realState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="realState.xsd"> 
    <estate> 
     <type>House</type> 
     <surface>250,0</surface> 
     <address> 
      <street>C/Tarragona</street> 
      <number>54</number> 
      <floor>2</floor> 
      <door>1</door> 
     </address> 
     <price>140000,0</price> 
    </estate> 
</realState> 

XSD代码:http://pastebin.com/nzEDsdLg

类房地产和地产工作OK!

谢谢!

回答

0

typesurface,和price不是<estate>元件的属性。它们是子元素。

要属性,XML是:

<estate type="House" surface="250,0" price="140000,0"> 
    <address> 
     <street>C/Tarragona</street> 
     <number>54</number> 
     <floor>2</floor> 
     <door>1</door> 
    </address> 
</estate> 

使用的StAX解析器比SAX解析器要容易得多,而且具有非常相似的性能特征,所以我建议你使用来代替。

+0

如果我不想更改XML代码,我需要更改什么? –

+0

删除'setType(attributes.getValue(“type”))''调用。我的意思是,你已经写了必要的代码来设置'endElement()'方法中的值,所以现在你试图设置两次值。 – Andreas

+0

好!我已经删除了它,但现在程序完成而不运行endElement方法。 –