XQuery 选择具有多个子元素包含相同属性值的元素

XQuery to select element with multiple children containing same attribute value

提问人:Radboud 提问时间:10/26/2023 最后编辑:Radboud 更新时间:10/26/2023 访问量:31

问:

我需要对 XML 文档库执行查询,以查找具有多个元素和非常特定项的记录。在 SQL 中,我会使用 GROUP BY、WHERE 和 HAVING。

我想选择它是否具有“过期”项目。如果项目是过去的,或者当该项目已被相同的新项目替换时,则该项目已过期。当有第二个项目具有更新的,也是过去或等于今天的时,就是这种情况。LoremlastDaytypefirstDay

不幸的是,我被限制为旧版本的 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>

我尝试了解决方案,但无法使其起作用。我的一些尝试:countfollowing-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

如果有更有效的方法,请告诉我。

XML XPath XQuery

评论

0赞 Michael Kay 10/26/2023
你还没有说你正在使用哪个版本的 XQuery。这里可能有一个使用“翻转窗口”(在 3.0 中可用)的解决方案。您也没有说是否所有具有相同物品的物品都是相邻的。@type

答:

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()