java xpath第一个可用值
我正在开发一个软件,在注册表(用户列表)上执行CRUD操作。没有打算使用DBMS,但是使用了大量带有Simple XML framework的XML
从整个列表中选择一部分用户,并由一个包含memento模式的java组件进行缓冲。这是为了保存状态和所选用户,以便能够从软件被终止的位置继续
我希望尽可能地精简xml memento文件,以便为每个用户创建一个唯一的索引,以避免为选定的用户写入所有数据
用户列表如下所示:
<users>
<user id="1">
<name> ... </name>
<role> ... </role>
</user>
<user id="2">
<name> ... </name>
<role> ... </role>
</user>
...
</users>
而纪念品文件是这样的:
<us>
<u>1</u>
...
<u>7</u>
</us>
现在。我还希望尽可能少地使用删除用户释放的索引来保持碎片。换句话说,如果我使用这个索引:
1 2 3 4
我添加了一个索引为5的用户
1 2 3 4 5
我删除了用户3
1 2 4 5
现在我想添加另一个用户,我希望分配的索引将是第一个可用的索引,在本例中为3,因此
1 2 3 4 5
请注意,可能有多个索引丢失,因此我不考虑使用变量或数据结构来保存被释放的值的历史,以便可以回收它们。我认为当我需要一个新的索引时,计算第一个可用的索引会更有效
最后,问题来了:有没有一种方法可以使用xPath获得缺少下一个值的第一个索引(抱歉,我找不到合适的词来描述这种值)
如果没有任何索引缺失,该表达式将收敛到其中的max(),否则它将返回缺失索引之前的值
当我想起忘记的细节时,我会更新这个问题。 致以最良好的祝愿
# 1 楼答案
使用XPath 1.0表达式:
这可以缩写为(可读性较差):
验证:
使用以下XSLT 1.0转换,只计算表达式并输出结果:
使用不同的“memento”XML文档,例如:
首先:
结果:8
秒:
结果:1
第三:
结果:7
第四:
结果:3
第五:
结果:4
第六:
结果:1
解释:
此解决方案中的XPath表达式是三个子表达式的总和:
a)
count(/*[not(u[not(text())])]/u)
b)
count(/*/u[not(text())][1]/preceding-sibling::u)
c)
1
/*/u
元素的计数,当它们都有一个文本子元素(在我们的特定情况下,是一个数字)。这里使用了双重否定的定律:对于任何序列无项不缺少一个给定的属性P,该序列具有其所有项都具有属性P的属性阅读更多关于双重否定法则的信息,这里:http://www.britannica.com/topic/law-of-double-negation和这里:https://en.wikipedia.org/wiki/Double_negation
在这种情况下,顺序是:
/*/u
属性p是:
u[text()]
换句话说,所有
/*/u
元素都有一个子文本节点我们只需要把
1
(expressionc)加到这个序列中的项数上,这就是这个特殊情况的解决方案正如我们马上就会看到的,每当表达式a)的计算结果为非零时,表达式b)的计算结果为零,反之亦然
/*/u
元素的前一个同级数。同样,在这种特殊情况下,解决方案只是添加1
(表达式c))为什么两个序列a)和b)的项数都不是零
之所以如此,是因为a)的项数非零,当且仅当其所有项都有一个文本子项时。在本例中,expressionb)不选择
u
元素,因为它们必须是另一个没有文本子元素的u
元素的前辈。然而,没有这样的元素,因为序列a中的所有元素(这些都是/*/u
元素)都有一个文本子元素