[英]Java 8 Stream API: get all nodes after specific Node
我有5个节点的org.w3c.dom.NodeList
。 由UUID.randomUUID();
生成的节点ID UUID.randomUUID();
Dom结构:
<section id="3" prefix="s1">
<paragraph id="value3">
...
</paragraph>
<paragraph id="value4">
...
</paragraph>
<paragraph id="value5">
...
</paragraph>
<paragraph id="value6">
...
</paragraph>
<paragraph id="value7">
...
</paragraph>
</section>
我需要获取属性为id =“ value5”的节点之后的所有节点。 因此结果应包含id = value6和id = value7的节点。
我创建了Stream<Element>
:
NodeList children = element.getChildNodes();
Stream<Element> elementStream = IntStream.range(0, children.getLength())
.mapToObj(children::item)
.filter(Element.class::isInstance)
.map(Element.class::cast);
因此,我可以通过Java 8 Stream API做到这一点吗?
不幸的是,DOM API无法与其他API很好地配合使用。 在此较早的答案中,我提供了一个有用的轻量级List
包装器。
这样,您可以简单地执行以下操作:
List<Node> list = XmlUtil.asList(element.getChildNodes());
list = list.subList(
list.indexOf(element.getOwnerDocument().getElementById("value5"))+1, list.size());
Stream<Element> stream = list.stream()
.filter(Element.class::isInstance).map(Element.class::cast);
要么
List<Node> list = XmlUtil.asList(element.getChildNodes());
Stream<Element> stream = IntStream.range(
list.indexOf(element.getOwnerDocument().getElementById("value5"))+1, list.size())
.mapToObj(list::get).filter(Element.class::isInstance).map(Element.class::cast);
您的问题令人困惑。 但是,如果您只需要在具有特定属性的Element之后获得节点并且它们是有序的,则可以尝试按其属性过滤Elements:
public List<Element> filterElements(NodeList items, int attributeStart){
List<Element> result = IntStream.range(0, items.getLength())
.mapToObj(children::item)
.filter(Element.class::isInstance)
.map(Element.class::cast)
.filter(e -> Integer.parseInt(e.getAttribute("id")) > attributeStart)
.collect(Collectors.toList());
return result;
}
我们决定将XPath
用于此任务。 看起来好多了:
private static final String EXPRESSION_TEMPLATE = "//*[@%s='%s']";
private static final String ID_ATTR = "id";
// some code here
@Override
public NodeList lookupSiblingsAfterId(Element aRootElement, String id) {
try {
if (null == id) {
throw new IllegalArgumentException("Invalid id parameter");
}
return (NodeList)xpath.newXPath().evaluate(String.format(EXPRESSION_TEMPLATE, ID_ATTR, id) + "[last()]/following-sibling::*", aRootElement, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
LOGGER.error("Can't evaluate XPath expression", e);
throw new RuntimeException(e);
}
}
我希望这会对某人有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.