我想从XML字符串中提取信息路径:
"/root/A/info1"
"/root/A/B/info2"
"/root/A/B/info3"
"/root/A/info4"
这是输入:
<root>
<A>
<info1>value1</info1>
<B>
<info2>value2.1</info2>
<info3>value3.1</info3>
</B>
<B>
<info2>value2.2</info2>
<!-- note: element "info3" is missing here! -->
</B>
<B>
<info2>value2.3</info2>
<info3>value3.3</info3>
</B>
<info4>value4</info4>
</A>
</root>
我想实现这个目标:
value1|value2.1|value3.1|value4
value1|value2.2|NULL|value4
value1|value2.3|value3.3|value4
我的路径各不相同,我从不知道XML文件的深度。由于"/root/A/B/info2"
和"/root/A/B/info3"
存在三次,我显然需要输出三行。
我认为这里需要递归。
我的代码:
主要功能:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
String[] paths = new String[] {"/root/A/info1", "/root/A/B/info2", "/root/A/B/info3", "/root/A/info4"};
XPath xPath = XPathFactory.newInstance().newXPath();
String[] output = new String[paths.length];
for(int i=0; i<paths.length; i++) {
recursion(paths, doc, xPath, paths[i], i, output);
}
递归函数:
private static void recursion(String[] paths, Object parent, XPath xPath, String path, int position, String[] output) throws Exception {
if(path.contains("/")) { // check if it's the last element, which contains the needed value
List<String> pathNodes = new ArrayList(Arrays.asList(StringUtils.split(path, "/")));
String currentPathNode = pathNodes.get(0);
NodeList nodeList = (NodeList) xPath.compile(currentPathNode).evaluate(parent, XPathConstants.NODESET);
pathNodes.remove(0);
String newPath = StringUtils.join(pathNodes, "/");
for(int i=0; i<nodeList.getLength(); i++) {
Node node = nodeList.item(i);
recursion(paths, node, xPath, newPath, position, output.clone()); // clone?
}
}
else {
output[position] = xPath.compile(path).evaluate(parent);
if((position + 1) == paths.length) { // check if it's the last path, so output the values
System.out.println(StringUtils.join(output, "|"));
}
}
}
如果我克隆output
,我会得到这个:
|||value4
如果我不克隆output
我得到了(覆盖以前的值):
value1|value2.3|value3.3|value4
请给我一个提示。
更新:再次查看XML输入。没有价值的文本元素可能会丢失。
答案 0 :(得分:0)
我终于解决了它。
我为我的应用程序添加了一个上下文路径。它指定哪个元素是最深的。
在我的示例中,它将是"/root/A/B"
。
我将所有路径更新为相对于该上下文路径:
"../info1"
"info2"
"info3"
"../info4"
然后我从上下文路径(这里是3
)计算节点。这也是将要创建的行数。我创建一个循环来迭代它们并使用XPath查询我更新的路径。