我需要对 XML 文档库执行查询,以查找包含多个元素(包含非常具体的项目)的记录。在 SQL 中,我会使用 GROUP BY、WHERE 和 HAVING。
如果有“过期”商品,我想选择
Lorem
。如果某个项目的 lastDay
已过去,或者该项目已被相同 type
的新项目替换,则该项目已过期。当第二个项目的 firstDay
也是过去或等于今天时,就会出现这种情况。
不幸的是,我仅限于旧版本的 XQuery,并且所使用的工具并不支持所有命令:AG Tamino。
lastDay
的查询很简单:/Lorem[ipsum[dolor[item[@lastDay <= '2023-10-24']]]]
查询多个相同类型的项目,其中所有
firstDay
都是过去或今天的,比较困难。
<?xml version="1.0" encoding="UTF-8"?>
<Lorem>
<ipsum>
<dolor>
<item id="1" type="ABC" firstDay="1980-01-01" />
<item id="2" type="ABC" firstDay="1985-01-01" lastDay="1990-01-01" />
<item id="3" type="ABC" firstDay="1995-01-01" />
<item id="4" type="DEF" firstDay="2000-01-01" />
<item id="5" type="DEF" firstDay="2023-10-25" lastDay="2050-01-01" />
<item id="6" type="GHI" firstDay="2000-01-01" lastDay="2023-10-24" />
<item id="7" type="GHI" firstDay="2050-01-01" />
</dolor>
</ipsum>
</Lorem>
我尝试了
count
和following-sibling
解决方案,但无法使其工作。我的一些尝试:
/Lorem[ipsum[dolor[
item[
@firstDay <= '2023-11-25' and
(
@type = *[@firstDay <= '2023-11-25']/@type
or
@type = *[@firstDay <= '2023-11-25']/@type
)
]
]]]
/Lorem[ipsum[dolor[
item[
@firstDay <= '2023-11-25' and
(
@type = preceding-sibling::[@firstDay <= '2023-11-25']/@type
or
@type = following-sibling::[@firstDay <= '2023-11-25']/@type
)
]
]]]
我想找到一个匹配项(两个具有相同类型且第一天之前/等于今天):
<?xml version="1.0" encoding="UTF-8"?>
<Lorem>
<ipsum>
<dolor>
<item id="1" type="ABC" firstDay="1980-01-01" />
<item id="2" type="ABC" firstDay="1985-01-01" />
<item id="4" type="DEF" firstDay="2000-01-01" />
</dolor>
</ipsum>
</Lorem>
但不在(没有相同类型,其中firstDay早于/等于今天)
<?xml version="1.0" encoding="UTF-8"?>
<Lorem>
<ipsum>
<dolor>
<item id="3" type="ABC" firstDay="1995-01-01" />
<item id="4" type="DEF" firstDay="2000-01-01" />
<item id="6" type="GHI" firstDay="2000-01-01" />
</dolor>
</ipsum>
</Lorem>
也不在(第二个相同类型的未来有firstDay)
<?xml version="1.0" encoding="UTF-8"?>
<Lorem>
<ipsum>
<dolor>
<item id="3" type="ABC" firstDay="1995-01-01" />
<item id="4" type="DEF" firstDay="2000-01-01" />
<item id="6" type="DEF" firstDay="2050-01-01" />
</dolor>
</ipsum>
</Lorem>
编辑:我使用 XQuery 找到了解决方案:
for $target in input()/Lorem
where
$target/ipsum/dolor/item/@lastDay <= xs:date('2023-11-24')
or
for $type in distinct-values($target/ipsum/dolor/item/@type)
where
count(
for $item in $target/ipsum/dolor/item
where $item/@firstDay <= xs:date('2023-11-25')
and $item/@type = $type
return $item
) > 1
return $type
return $target
如果有更有效的方法,请告诉我。
在我看来有点像
some $item in $Lorem//item satisfies
some $earlier-item
in $item/preceding-sibling::item[@type eq $item/@type]
satisfies xs:date($earlier-item/@firstDay) lt current-date()