Add a quantifier (*
,+
,...) to your \d
. Try
'^VAL\d*$'
As @kjhughes has pointed out. This will not work with standard Java, because even current version of Java 11 does not support XPath 2.0.
You can however use Saxon if you need XPath 2.0 support.
Saxon Example (It is a variant of this answer using javax.xml)
Processor processor = new Processor(false);
@Test
public void xpathWithSaxon() {
String xml = "<root><tagA attA=\"VAL1\">text</tagA>\n" + "<tagB attB=\"VAL333\">text</tagB>\n"
+ "<tagA attA=\"VAL2\">text</tagA>\n" + "<tagA attA=\"V2\">text</tagA>\n" + "</root>";
try (InputStream in = new ByteArrayInputStream(xml.getBytes("utf-8"));) {
processFilteredXmlWith(in, "//root/tagA[matches(@attA,'^VAL\\d*$')]", (node) -> {
printItem(node, System.out);
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void printItem(XdmItem node, PrintStream out) {
out.println(node);
}
public void processFilteredXmlWith(InputStream in, String xpath, Consumer<XdmItem> process) {
XdmNode doc = readXmlWith(in);
XdmValue list = filterNodesByXPathWith(doc, xpath);
list.forEach((node) -> {
process.accept(node);
});
}
private XdmNode readXmlWith(InputStream xmlin) {
try {
return processor.newDocumentBuilder().build(new StreamSource(xmlin));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private XdmValue filterNodesByXPathWith(XdmNode doc, String xpathExpr) {
try {
return processor.newXPathCompiler().evaluate(xpathExpr, doc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Prints
<tagA attA="VAL1">text</tagA>
<tagA attA="VAL2">text</tagA>