[英]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.