Javaでは、 NamedNodeMap インターフェースを見て、ジェネリックスでどのように反復しますか? StringではなくNodeを使用しているようですが、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());
}
}
これ以上良いものはありませんか?
これらのAPIを使用するためのより良い方法はないと思います。 (更新:OK-多分 https://stackoverflow.com/a/28626556/139985 ニースとしてカウントされます。)
W3C DOM Java APIはJavaがジェネリックまたは新しいfor
構文、さらにはIterator
interface。JavaのW3CDOM APIは、実際にはIDL仕様をJavaにマッピングした結果であることに注意してください。
メモリ内のXMLなどを操作するためのより優れたAPIが必要な場合は、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());
}
}
同様のアプローチで、Map.Entry<String, String>
インスタンス上にIterable
を作成できます。
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);
}
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++);
}
};
}