Android XPath读取失败:EBADF

时间:2013-07-12 13:02:54

标签: android xml xpath

我正在使用XPath来读取本地存储在内部存储中的Xml文件的内容。

我有两种方法。每个都从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;
    }
}

1 个答案:

答案 0 :(得分:0)

我终于解决了。如你所说,文件的结尾已在流中到达。为了解决这个问题,我抓住了Xml根节点,并在所有后续XPath.evaluate调用中使用它而不是源代码。这样我第一次调用后就不需要打开流来评估我抓住根节点的位置了!死了chuffed我解决了:)