gpt4 book ai didi

java - xpath 第一个可用值

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:06 24 4
gpt4 key购买 nike

我正在开发一个软件来对注册表(用户列表)执行 CRUD 操作。不打算使用任何 DBMS,而是使用大量带有 Simple XML framework 的 XML。 .

从整个列表中,将选择用户的子集,并通过包含备忘录模式的 Java 组件进行缓冲。这是为了保存状态和所选用户能够从 SW 被杀死的地方继续。

我希望使 xml 备忘录文件尽可能精简,因此我脑海中浮现出每个用户的唯一索引,以避免写入所选用户的所有数据。

用户列表如下:

<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(),否则它将返回缺失索引之前的值。

当我想起我忘记的细节时,我会更新这个问题。谨致问候,

最佳答案

使用此 XPath 1.0 表达式:

 count(/*[not(u[not(text())])]/u) 
+
count(/*/u[not(text())][1]/preceding-sibling::u)
+ 1
<小时/>

这可以缩写为(可读性较差):

count(
/*[not(u[not(text())])]/u
|
/*/u[not(text())][1]/preceding-sibling::u
)
+ 1
<小时/>

验证:

使用 XSLT 1.0 转换,仅计算表达式并输出结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="node()|@*">
<xsl:value-of select=
"count(/*[not(u[not(text())])]/u)
+
count(/*/u[not(text())][1]/preceding-sibling::u)
+ 1"
/>
</xsl:template>
</xsl:stylesheet>

具有不同的“备忘录”XML 文档,例如:

第一:

<us>
<u>1</u>
<u>2</u>
<u>3</u>
<u>4</u>
<u>5</u>
<u>6</u>
<u>7</u>
</us>

结果:8

第二:

<us>
<u></u>
<u>2</u>
<u>3</u>
<u>4</u>
<u>5</u>
<u>6</u>
<u>7</u>
</us>

结果:1

第三:

<us>
<u>1</u>
<u>2</u>
<u>3</u>
<u>4</u>
<u>5</u>
<u>6</u>
<u></u>
</us>

结果:7

第四:

<us>
<u>1</u>
<u>2</u>
<u></u>
<u>4</u>
<u>5</u>
<u>6</u>
<u>7</u>
</us>

结果:3

第五:

<us>
<u>1</u>
<u>2</u>
<u>3</u>
<u></u>
<u>5</u>
<u></u>
<u>7</u>
</us>

结果:4

第六:

<us>
</us>

结果:1

<小时/>

说明:

此解决方案中的 XPath 表达式是三个子表达式的总和:

a) count(/*[not(u[not(text())])]/u)

b) count(/*/u[not(text())][1]/preceding-sibling::u)

c) 1

  1. 表达式a)是所有/*/u元素的计数,当所有/*/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 (表达式 c) )添加到此序列中的项目数,这就是此特定情况的解决方案。

正如我们稍后将看到的,每当表达式 a) 计算结果为非零时,表达式 b) 计算结果为零,反之亦然。

  • 表达式 b) 是没有文本子元素的第一个 /*/u 元素的前同级元素的数量。同样,这种特殊情况下的解决方案只需添加 1 (表达式 c) )
  • 为什么两个序列a)b)不能同时具有非零数量的项目?

    之所以如此,是因为当且仅当 a) 的所有项目都有一个文本子项时,它的项目数才非零。在本例中,表达式 b) 不选择任何 u 元素,因为它们必须是另一个没有文本子级的 u 元素的前同级元素。但是,不存在这样的元素,因为序列 a) 中的所有元素(这些都是 /*/u 元素)都有一个文本子元素。

    关于java - xpath 第一个可用值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37011681/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com