2013-07-12 39 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我工作了:)