2013-07-12 63 views
0

我正在使用XPath讀取本地存儲在內部存儲中的Xml文件的內容。Android XPath讀取失敗:EBADF

我有兩種方法。每個都從xml文件獲取數據。第一種方法運行良好並且可行。除了查找不同的數據之外,第二種方法與第一種方法幾乎相同。但是,這種讀取失敗的方法失敗:EBADF。

生成錯誤的行位於ProcessEscalationLevels方法中。

NodeList nodes = (NodeList) xPath.evaluate(expression, source, 
      XPathConstants.NODESET); 

下面是兩種獲取數據和調用方法的方法。有誰知道什麼可能導致這個錯誤?我認爲它認爲文件流已關閉,但無法解決原因。

public void processSiteFile(File sitexml) throws IOException, 
     XPathExpressionException { 
    this.sitexml = sitexml; 

    FileInputStream stream = new FileInputStream(this.sitexml); 
    try { 
     InputSource source = new InputSource(stream); 
     XPath xPath = XPathFactory.newInstance().newXPath(); 

     // emergency category names 
     processCategoryNames(xPath, source); 

     // Process escalation levels 
     processEscalationLevels(xPath, source); 

    } finally { 
     stream.close(); 
    } 
} 

private void processEscalationLevels(XPath xPath, InputSource source) 
     throws XPathExpressionException, FileNotFoundException { 

    String expression = "/site_settings/group_category_permission_list" 
      + "/group_category_permission"; 
    NodeList nodes = (NodeList) xPath.evaluate(expression, source, 
      XPathConstants.NODESET); 

    if (nodes != null && nodes.getLength() > 0) { 
     for (int i = 0; i < nodes.getLength(); i++) { 
      Element entry = (Element) nodes.item(i); 

      // extract group id 
      String tmpGroupId = xPath.evaluate("group_id", entry); 
      int groupId = 0; 
      if (tmpGroupId != null) { 
       try { 
        groupId = Integer.valueOf(tmpGroupId); 
       } catch (NumberFormatException e) { 
        groupId = 0; 
       } 
      } 

      // extract category name 
      String categoryName = xPath.evaluate("category_name", entry); 
      if (categoryName == null) 
       categoryName = ClientData.DEFAULT_CATEGORY; 

      ClientData.GroupPermission permission = 
        new ClientData.GroupPermission(groupId, categoryName); 

      // extract escalation levels and add to permission 
      NodeList permissionNodes = (NodeList) xPath.evaluate(
        "escalation_level_list/escalation_level", entry, 
        XPathConstants.NODESET); 

      for (int e = 0; e < permissionNodes.getLength(); e++) { 
       Element permEntry = (Element) permissionNodes.item(e); 

       // get seconds before escalating 
       String tmpSecsBeforeEscalating = xPath.evaluate(
         "secs_before_escalating", permEntry); 
       int secsBeforeEscalating = 0; 
       if (tmpSecsBeforeEscalating == null) { 
        secsBeforeEscalating = ClientData.DEFAULT_ESCALATION_TIME; 
       } else { 
        secsBeforeEscalating = Integer 
          .valueOf(tmpSecsBeforeEscalating); 
       } 

       // get list of target group ids 
       NodeList targetGroupNodes = (NodeList) xPath.evaluate(
         "target_group_id_list/target_group_ids", permEntry, 
         XPathConstants.NODESET); 
       Set<Integer> targetGroups = new HashSet<Integer>(); 
       for (int o = 0; o < targetGroupNodes.getLength(); o++) { 
        Node groupEntry = (Node) targetGroupNodes.item(o); 
        targetGroups.add(Integer.valueOf(groupEntry 
          .getTextContent())); 
       } 

       permission.escalationLevels 
         .add(permission.new EscalationLevel(targetGroups, 
           secsBeforeEscalating)); 
      } 

      // Add permission to permission list 
      ClientData.groupPermissions.add(permission); 
     } 
    } 
} 

private void processCategoryNames(XPath xPath, InputSource source) 
     throws XPathExpressionException { 
    String expression = "/site_settings/emergency_category_list" 
      + "/emergency_category"; 
    NodeList nodes = (NodeList) xPath.evaluate(expression, source, 
      XPathConstants.NODESET); 

    if (nodes != null && nodes.getLength() > 0) { 
     List<String> categories = new ArrayList<String>(); 

     for (int i = 0; i < nodes.getLength(); i++) { 
      Node entry = nodes.item(i); 

      if (entry.getNodeName() == "name") { 
       categories.add(entry.getTextContent()); 

      } else if (entry.getNodeName() == "secs_before_repeating") { 
       ClientData.secsBeforeRepeatingEmergency = Integer 
         .valueOf(entry.getTextContent()); 
      } 
     } 

     // Write category list to ClientData 
     ClientData.emergencyCategory = (String[]) categories.toArray(); 

    } else { 

     // Write a default category and repeat time 
     ClientData.emergencyCategory = new String[] { 
      ClientData.DEFAULT_CATEGORY 
     }; 
     ClientData.secsBeforeRepeatingEmergency = 
       ClientData.DEFAULT_EMERGENCY_REPEAT_TIME; 
    } 
} 
+0

我不熟悉InputSources,但我看到它包裝InputStream。在這一點上,流的末端可能已經達到了?您可能想嘗試通過線性XPath讀取源代碼;也就是說,評估XML就好像文件指針只能繼續前進一樣。如果問題依然存在,那麼您必須爲我提供XML以使其發揮作用。 –

+0

嗨保羅,是的,我終於搞定了。正如你所說的那樣,文件的末尾已經到達了流中。爲了解決這個問題,我抓取了Xml根節點,並在隨後調用XPath.evaluate時使用該節點,而不是源代碼。這樣我就不需要在第一次調用之後打開流來評估我抓取根節點的位置!死了chuffed我工作了:) – Stephen

回答

0

我終於搞定了。正如你所說的那樣,文件的末尾已經到達了流中。爲了解決這個問題,我抓取了Xml根節點,並在隨後調用XPath.evaluate時使用該節點,而不是源代碼。這樣我就不需要在第一次調用之後打開流來評估我抓取根節點的位置!死了chuffed我工作了:)