我解析了一个非常大的xml文件(来自jpylyzer,一个jp2属性提取器)。此xml包含许多JP2图像的属性,每个图像具有相同的元素,如:
//results/jpylyzer/fileInfo/fileName
//results/jpylyzer/properties/jp2HeaderBox/imageHeaderBox/height
//results/jpylyzer/properties/jp2HeaderBox/imageHeaderBox/width
//results/jpylyzer/properties/jp2HeaderBox/imageHeaderBox/bPCDepth
为了减少处理时间,我使用这种方法:
for (XPathExpression xPathExpression : listXPathExpression) {
nodeList = (NodeList) xPathExpression.evaluate(document, XPathConstants.NODESET);
//we use our list
}
它非常方便快捷,但元素数量必须与我们对每个属性的预期一致。 由于某些属性对于某些图像是唯一的,因此某些图像不会找到某些xpath值。
nodeList仅使用找到的值填充,这是一个问题:无法将这些值与其他值匹配,因为列表不具有相同的大小,具体取决于找到的属性数量。
有没有办法填补"空白"什么时候找不到值?
答案 0 :(得分:1)
使用单个XPath表达式无法实现所需的功能,即使版本2.0也是如此。在这种情况下,您必须使用嵌入XPath的更高级语言。
由于我不太熟悉Java,我不能给你特定的代码,但我可以解释你必须做什么。
我假设一个类似于
的XML文档<results>
<jpylyzer>
<fileInfo>
<fileName>Name of file</fileName>
</fileInfo>
<properties>
<jp2HeaderBox>
<imageHeaderBox>
<height>45</height>
<width>66</width>
<bPCDepth>386</bPCDepth>
</imageHeaderBox>
<imageHeaderBox>
<width>32</width>
</imageHeaderBox>
</jp2HeaderBox>
</properties>
</jpylyzer>
</results>
作为一个起点,在所有情况下,找到所有XML文档中确实存在 的元素。为了举例,我们假设imageHeaderBox
遍布各地,但其子height
,width
和bPCDepth
不一定存在。
查找imageHeaderBox
元素的XPath表达式:
/results/jpylyzer/properties/imageHeaderBox
计算表达式并将结果保存到nodeList。接下来,进一步处理此列表。这只适用于XPath表达式可以应用于nodeList
中的各个项目,但似乎您对此持乐观态度:
我可以遍历nodelist。我想我也可以评估
迭代nodeList
(imageHeaderBox
表达式的结果)并对每个项目应用另一个路径表达式。
XPath 2.0
在XPath 2.0中,您可以使用if
/ then
语句检查节点是否存在。假设imageHeaderBox
元素节点作为上下文项:
if(height) then height else 'e.g. text saying there is no height'
XPath 1.0
使用XPath 1.0,它稍微复杂一些:
concat(height, substring('e.g. text saying there is no height', 1 div not(height)))"
请参阅Dimitre Novatchev的回答here以获得解释。这种技术被称为Becker方法,可能是here。
最后,结果列表应与
类似45
e.g. text saying there is no height