使用 XPathExpression 和 NODESET 评估许多元素

Evaluate many elements with XPathExpression and NODESET

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

没有找到值时,有没有办法填充"blank"?

单个 XPath 表达式无法满足您的需求,即使是 2.0 版也是如此。在这种情况下,您必须使用嵌入 XPath 的 higher-level 语言。

由于我对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 无处不在,但其 children heightwidthbPCDepth 不一定存在。

查找 imageHeaderBox 元素的 XPath 表达式:

/results/jpylyzer/properties/imageHeaderBox

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

I can iterate over nodelist. I guess i can evaluate too

遍历 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 for an explanation. The technique is known as the Becker method, probably introduced here

最后,结果列表应该类似于

45
e.g. text saying there is no height