在Java中,查看NamedNodeMap界面,如何使用泛型进行迭代?它似乎使用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());
}
}
什么都没有?
答案 0 :(得分:8)
您可以为Iterable
创建自己的NamedNodeMap
包装,然后在 foreach 循环中使用它。
例如,这可能是一个简单的实现:
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());
}
}
使用类似方法,您可以创建Iterable
个Map.Entry<String, String>
个实例。
答案 1 :(得分:7)
我认为没有更好的方法来使用这些API。 (更新:好的 - 也许https://stackoverflow.com/a/28626556/139985很好。)
请记住,W3C DOM Java API是在Java具有泛型或新for
语法,甚至是Iterator
接口之前指定的。还要记住,用于Java的W3C DOM API实际上是将IDL规范映射到Java的结果。
如果你想在内存中使用更好的API来操作XML等,也许你应该看一下JDOM。
答案 2 :(得分:4)
由于你无法将NamedNodeMap转换为Map,我建议使用经典的for循环来循环:
int numAttrs = namedNodeMap.getLength();
System.out.println("Attributes:");
for (int i = 0; i < numAttrs; i++){
Attr attr = (Attr) pParameterNode.getAttributes().item(i);
String attrName = attr.getNodeName();
String attrValue = attr.getNodeValue();
System.out.println("\t[" + attrName + "]=" + attrValue);
}
答案 3 :(得分:0)
从Java 8解决方案开始:
private static Iterable<Node> iterableNamedNodeMap(final NamedNodeMap namedNodeMap) {
return () -> new Iterator<Node>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < namedNodeMap.getLength();
}
@Override
public Node next() {
if (!hasNext())
throw new NoSuchElementException();
return namedNodeMap.item(index++);
}
};
}