提问人:Radboud 提问时间:10/26/2023 最后编辑:Radboud 更新时间:10/26/2023 访问量:31
XQuery 选择具有多个子元素包含相同属性值的元素
XQuery to select element with multiple children containing same attribute value
问:
我需要对 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>
但不在(没有与前一天/等于今天的相同类型)
<?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>
也不在(第二个与相同类型的人将来有第一天)
<?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
如果有更有效的方法,请告诉我。
答:
0赞
Michael Kay
10/26/2023
#1
在我看来,这有点像
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()
评论
@type