使用 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 height
、width
和 bPCDepth
不一定存在。
查找 imageHeaderBox
元素的 XPath 表达式:
/results/jpylyzer/properties/imageHeaderBox
计算表达式并将结果保存到 nodeList。接下来,进一步处理这个列表。这仅在 XPath 表达式可以应用于 nodeList
中的单个项目时有效,但您似乎对此持乐观态度:
I can iterate over nodelist. I guess i can evaluate too
遍历 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 for an explanation. The technique is known as the Becker method, probably introduced here。
最后,结果列表应该类似于
45
e.g. text saying there is no height
我解析了一个非常大的 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 height
、width
和 bPCDepth
不一定存在。
查找 imageHeaderBox
元素的 XPath 表达式:
/results/jpylyzer/properties/imageHeaderBox
计算表达式并将结果保存到 nodeList。接下来,进一步处理这个列表。这仅在 XPath 表达式可以应用于 nodeList
中的单个项目时有效,但您似乎对此持乐观态度:
I can iterate over nodelist. I guess i can evaluate too
遍历 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 for an explanation. The technique is known as the Becker method, probably introduced here。
最后,结果列表应该类似于
45
e.g. text saying there is no height