2011-06-10 46 views
3

我想使用薩克斯解析器與自定義的DefaultHandler,但奇怪的事情,在dHandler startElement()方法永遠不會被調用。調用endDocument()的作品,因爲它應該,但它打印java薩克斯程序不去startElement()方法

Total elements:0 

,而我的XML文件的類型是「國家」的11個元素。

如果即使我把總++放在if語句之外,所以它每次都會增加startElement()被調用,它仍然會說0個元素。

請幫我這句話,謝謝

if(e.getSource()==open) 
    { 
     JFileChooser chooseFile=new JFileChooser(); 
     int returnVal = chooseFile.showOpenDialog(wnd); 
     if (returnVal == JFileChooser.APPROVE_OPTION) { 
      File file = chooseFile.getSelectedFile(); 

       //This is where a real application would open the file. 
       parser.parse(new InputSource(new FileInputStream(file))); 
       DocumentImpl document = (DocumentImpl)parser.getDocument(); 
       Node root = document.getLastChild(); 
       AllElements allelements = new AllElements(); 
       NodeIteratorImpl iterator =(NodeIteratorImpl)document.createNodeIterator(root, 
     NodeFilter.SHOW_ELEMENT, (NodeFilter)allelements, true); 
       Node n; 
       states.removeAll(states); 
       while ((n = iterator.nextNode()) != null) 
       { 

        if(n.getNodeName().equals("state")) 
        { 
         NamedNodeMap attrs = n.getAttributes(); 
         NodeList children=n.getChildNodes(); 
         State newState=new State(attrs.item(0).getNodeValue(), 
           attrs.item(1).getNodeValue(),attrs.item(2).getNodeValue(),attrs.item(3).getNodeValue(),children.item(0).getTextContent()); 
         states.add(newState); 

        } 

       } 
       Collections.sort(states,new StateComparator()); 
       mod.setRowCount(states.size()); 
       mod.setColumnCount(5); 
       for(int i=0;i<states.size();i++) 
       { 
        mod.setValueAt(states.get(i).abbr, i, 0); 

        mod.setValueAt(states.get(i).name, i, 1); 
        mod.setValueAt(states.get(i).population_2k10, i, 2); 
        mod.setValueAt(states.get(i).rank_2k, i, 3); 
        mod.setValueAt(states.get(i).census_1990, i, 4); 
       } 

       mean=0; 
       max=MAXIMUM; 
       min=MINIMUM; 
       count=0; 
        total=0; 
        SAXParserFactory parserFact = SAXParserFactory.newInstance(); 
     SAXParser parserS = parserFact.newSAXParser(); 
     DefaultHandler dHandler = new DefaultHandler(){ 
      public void startElement(String uri, String name, String element, Attributes atri) 
          { 
       if (element.equals("state")){ 
        total++; 
       } 
      } 
      public void endDocument(){ 
       System.out.println("Total elements: " + total); 
      } 
     }; 
        parserS.parse(file, dHandler); 
        meanL.setText("mean="+mean); 
        maxL.setText("max="+max); 
        minL.setText("min="+min); 
        countL.setText("count="+total); 
     } else { 

     } 

    } 
+1

順便說一句,你不應該使用SAX的實現類,像DocumentImpl。使用界面文檔。 – MeBigFatGuy 2011-06-10 03:47:31

+0

你的代碼是如何在第一個地方編譯的?你的'DefaultHandler'實現是一個匿名的本地類;其中引用的'total'變量必須是'final'。 – 2011-06-10 04:06:33

回答

0

我想你的意思是該元素的名稱是「國家」。如果是這樣,在DefaultHandler.startElement執行以下行應該是:

if (name.equals("state")){ 
    total++; 
} 

,而不是

if (element.equals("state")){ 
    total++; 
} 

的第三個參數給startElement方法實際上是QNAME。如果不存在名稱空間前綴,它將爲空;如果前綴存在,那麼它將被填充。

編輯

它不會出現原來的代碼進行編譯,至少不反對甲骨文/ Sun的Java編譯器6,我用。下面就來看看什麼DefaultHandler類的實現應該像,如果總的元素將被計:

DefaultHandler handler = new DefaultHandler() { 

    public int total = 0; 

    public void startElement(String uri, String name, String qName, 
      Attributes atri) { 
     if (qName.equals("state")) { 
      total++; 
     } 
    } 

    public void endDocument() { 
     System.out.println("Total elements: " + total); 
    } 
}; 

注意,總可變現在是匿名類的成員。如果不是,則必須在外部類中聲明爲final,這會使其不可變(將增量操作呈現爲非法)。但是,不能從匿名類外部訪問總變量。我建議將DefaultHandler類擴展到不同的類中,並使用該處理程序實現,以使事情變得簡單。

+0

是的,我已經嘗試過 - 但它得到完全相同的結果,我描述 - 「總元素:0」。它甚至會說「Total elements:0」,當我刪除這個if語句並且只留下總數+ – Anton 2011-06-10 03:41:27

+0

@Anton時,請參閱我的編輯。如果可以,請忽略我的第一個答案。 – 2011-06-10 04:19:24

1

也許你沒有正確覆蓋默認startElement()。如果向該方法添加一個@Override註釋,則不應該得到編譯時錯誤。如果你這樣做,那麼聲明startElement(...)(你沒有顯示)是不正確的。

編輯:你startElement聲明只需要看起來像這樣:

void startElement(
    String uri, 
    String localName, 
    String qName, 
    Attributes attributes) 

參數名稱可以不同,但​​參數的數量和類型必須完全匹配。

+0

這正是你所描述的!我曾嘗試添加@Override之前 - 它給了我錯誤。你能否給我一個關於改變什麼的暗示? – Anton 2011-06-10 03:51:43

+0

請編輯您的帖子,以顯示您如何聲明您的處理程序類以及'startElement()'方法的聲明。 @Override註釋可以幫助您找到這種問題。如果你認爲你壓倒一切,它會告訴你,如果你沒有正確地聲明它。 – 2011-06-10 03:54:47

+0

我還沒有在任何地方聲明 - DefaultHandler是一個適配器類,所以我只是重新定義了方法。在DefaultHandler中,此方法聲明爲:public void startElement(String uri,String localName,String qName,Attributes attributes),即完全使用我已使用的相同參數。 – Anton 2011-06-10 04:02:31

16

請檢查該屬性參數的import語句,它應該是:

import org.xml.sax.Attributes; 

問候

+1

不錯,Eclipse自動完成的首選是java.util.jar;改變參考可以解決問題。 – htafoya 2012-04-11 15:17:20