NamedNodeMap 的通用 foreach 迭代

2022-09-02 01:45:18

在Java中,看看NameNodeMap接口,你如何用泛型迭代它?它似乎使用Node而不是String,但我不太确定如何使用Node对象...

NamedNodeMap namedNodeMap = doc.getAttributes();
Map<String, String> stringMap = (Map<String, String>) namedNodeMap;
for (Map.Entry<String, String> entry : stringMap.entrySet()) {
  //key,value stuff here
}

是的,我可以看到如何在不使用泛型和常规for循环的情况下进行迭代,但我想使用上面的?成语?用于地图。当然,问题似乎在于,尽管有这个名字,NamedNodeMap实际上并没有实现Map接口!:(

猜猜你只需要在这里咬紧牙关,做这样的事情:

/*
 * Iterates through the node attribute map, else we need to specify specific 
 * attribute values to pull and they could be of an unknown type
 */
private void iterate(NamedNodeMap attributesList) {
    for (int j = 0; j < attributesList.getLength(); j++) {
        System.out.println("Attribute: "
                + attributesList.item(j).getNodeName() + " = "
                + attributesList.item(j).getNodeValue());
    }
}

没有什么比这更好的了?


答案 1

您可以创建自己的包装器,然后在 foreach 循环中使用它。IterableNamedNodeMap

例如,这可能是一个简单的实现:

public final class NamedNodeMapIterable implements Iterable<Node> {

    private final NamedNodeMap namedNodeMap;

    private NamedNodeMapIterable(NamedNodeMap namedNodeMap) {
        this.namedNodeMap = namedNodeMap;
    }

    public static NamedNodeMapIterable of(NamedNodeMap namedNodeMap) {
        return new NamedNodeMapIterable(namedNodeMap);
    }

    private class NamedNodeMapIterator implements Iterator<Node> {

        private int nextIndex = 0;

        @Override
        public boolean hasNext() {
            return (namedNodeMap.getLength() > nextIndex);
        }
        @Override
        public Node next() {
            Node item = namedNodeMap.item(nextIndex);
            nextIndex = nextIndex + 1;
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

    }

    @Override
    public Iterator<Node> iterator() {
        return new NamedNodeMapIterator();
    }
}

在这种情况下,这将是用法:

private void iterate(NamedNodeMap attributesList) {
    for (Node node : NamedNodeMapIterable.of(attributesList)) {
        System.out.println("Attribute: "
                + node.getNodeName() + " = " + node.getNodeValue());
    }
}

使用类似的方法,您可以创建一个 over 实例。IterableMap.Entry<String, String>


答案 2

我不认为有更好的方法来使用这些API。(更新:好的 - 也许 https://stackoverflow.com/a/28626556/139985 算不错。

请记住,W3C DOM Java API 是在 Java 具有泛型或新语法甚至接口之前指定的。还要记住,用于 Java 的 W3C DOM API 实际上是将 IDL 规范映射到 Java 的结果。forIterator

如果你想要更好的API来操作内存中的XML等,也许你应该看看JDOM。