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

问题描述 投票:0回答:1

我需要对 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

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

xml xpath xquery
1个回答
0
投票

在我看来有点像

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()
© www.soinside.com 2019 - 2024. All rights reserved.