0

I am using XPath to read the contents of an Xml file stored locally in internal storage.

I have two methods. Each gets data from the xml file. The first method runs fine and works. The second method is almost the same as the first except it looks for different data. However, this method errors with read failed: EBADF.

The line that generates the error is in the ProcessEscalationLevels method.

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

The two methods that get data plus the calling methods are below. Does anyone know what could be causing this error? I figure that it thinks the file stream is closed but am unable to work out why.

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;
    }
}
4

1 回答 1

0

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

于 2013-07-12T14:11:06.913 回答