使用XPathExpression和NODESET评估许多元素

时间:2015-01-12 09:53:58

标签: java xml xpath

我解析了一个非常大的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仅使用找到的值填充,这是一个问题:无法将这些值与其他值匹配,因为列表不具有相同的大小,具体取决于找到的属性数量。

有没有办法填补"空白"什么时候找不到值?

1 个答案:

答案 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遍布各地,但其子heightwidthbPCDepth不一定存在。

查找imageHeaderBox元素的XPath表达式:

/results/jpylyzer/properties/imageHeaderBox

计算表达式并将结果保存到nodeList。接下来,进一步处理此列表。这只适用于XPath表达式可以应用于nodeList中的各个项目,但似乎您对此持乐观态度:

  

我可以遍历nodelist。我想我也可以评估

迭代nodeListimageHeaderBox表达式的结果)并对每个项目应用另一个路径表达式。

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