值提取系列
字符串值提取工具-04-java 调用 java? Janino 编译工具
字符串值提取工具-08-java 通过 xml-path 解析 xml
字符串值提取工具-09-java 执行 json 解析, json-path
场景
我们希望通过 java 执行 xml-path 解析 xml。
基础支持
核心实现
代码
/**
*
* @since 0.4.0
*/
public class ValueExtractionXmlPath extends AbstractValueExtractionAdaptor<Document> {
// 创建 XPath 对象
private final XPathFactory xPathFactory = XPathFactory.newInstance();
private final XPath xpath = xPathFactory.newXPath();
@Override
protected Document prepare(ValueExtractionContext context) {
try {
final String xml = (String) context.getDataMap().get("xml");
// 将 XML 字符串解析为 Document 对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
return document;
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected Object evaluate(Document prepareObject, String script, ValueExtractionContext context) {
try {
// 编译并执行 XPath 表达式
XPathExpression expr = xpath.compile(script);
return expr.evaluate(prepareObject);
} catch (XPathExpressionException e) {
throw new RuntimeException(e);
}
}
}
测试代码
@Test
public void test() {
String xml = " <company>\n" +
" <employee>\n" +
" <name>John Doe</name>\n" +
" <position>Software Engineer</position>\n" +
" <salary>75000</salary>\n" +
" </employee>\n" +
" <employee>\n" +
" <name>Jane Smith</name>\n" +
" <position>Project Manager</position>\n" +
" <salary>85000</salary>\n" +
" </employee>\n" +
" </company>";
// 测试 getValueByXPath 方法
String script = "//employee[1]/name/text()";
// 创建绑定并设置参数
Map<String, Object> bindings = new HashMap<>();
bindings.put("xml", xml);
String result = ValueExtractionBs.newInstance()
.scripts(Arrays.asList(script))
.valueExtraction(ValueExtractions.xmlPath())
.dataMap(bindings)
.extract().toString();
Assert.assertEquals("{//employee[1]/name/text()=John Doe}", result);
}