package tc.oc.parse.xml;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import tc.oc.commons.core.util.Streams;
import tc.oc.parse.MissingException;
import tc.oc.parse.ParseException;
public class XML {
public static Stream<Node> nodes(NodeList nodeList) {
return IntStream.range(0, nodeList.getLength())
.mapToObj(nodeList::item);
}
public static Stream<Element> elements(NodeList nodeList) {
return Streams.instancesOf(IntStream.range(0, nodeList.getLength())
.mapToObj(nodeList::item),
Element.class);
}
public static Stream<Node> childNodes(Node parent) {
return nodes(parent.getChildNodes());
}
public static Stream<Element> children(Element parent) {
return elements(parent.getChildNodes());
}
public static Stream<Element> childrenNamed(Element parent, String... names) {
return childrenNamed(parent, Arrays.asList(names));
}
public static Stream<Element> childrenNamed(Element parent, Collection<String> names) {
switch(names.size()) {
case 0: return Stream.empty();
case 1: return elements(parent.getElementsByTagName(names.iterator().next()));
default: return children(parent).filter(element -> names.contains(element.getTagName()));
}
}
public static Optional<Attr> attr(Element parent, String name) {
return Optional.ofNullable(parent.getAttributeNode(name));
}
public static Optional<String> attrValue(Element parent, String name) {
return attr(parent, name).map(Attr::getValue);
}
public static Attr requireAttr(Element parent, String name) throws ParseException {
final Attr attr = parent.getAttributeNode(name);
if(attr == null) {
throw new MissingException("attribute", name);
}
return attr;
}
}