Добавьте квантификатор (*
, +
, ...) к вашему \d
.Попробуйте
'^VAL\d*$'
Как указало @ kjhughes .Это не будет работать со стандартной Java, потому что даже текущая версия Java 11 не поддерживает XPath 2.0.Однако вы можете использовать Saxon , если вам нужна поддержка XPath 2.0.
Саксонский пример (Это вариант ответа с использованием 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>