общая итерация foreach NamedNodeMap
в Java, глядя на NamedNodeMap интерфейс, как вы повторяете его с дженериками? Кажется, он использует узел, а не строку, но я не уверен, как использовать объекты узла...
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 фактически не реализует интерфейс карты! :(
думаю, вы просто должны укусить пулю здесь и сделать что-то вроде:
/*
* 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());
}
}
нет ничего милее?
3 ответов
Я не думаю, что есть лучший способ использовать эти API.
имейте в виду, что API Java W3C DOM были указаны до того, как Java имела дженерики или новый for
синтаксис, или даже Iterator
интерфейс. Также имейте в виду, что API W3C DOM для Java на самом деле являются результатом сопоставления спецификации IDL с Java.
Если вы хотите более приятные API для управления XML и т. д. В памяти, возможно, вам стоит посмотреть JDOM.
вы можете создать свой собственный 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>
экземпляров.
Как вы не можете разыграть NamedNodeMap до карта, Я предлагаю использовать классический цикл для цикла:
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);
}