如何计算xml文件中特定属性的出现次数?

时间:2015-03-31 23:19:31

标签: xml database xquery

鉴于以下xml文件,我需要报告少于4个关注者和关注者的uid的用户的uid。

<!DOCTYPE users SYSTEM "users.dtd">
<users>
 <user uid = "u1" dob = "06/03/94" email = "tom@hotmail.com">
    <surname> Doe</surname>
    <givennames> Jon </givennames>
    <follows who = "u1 u2"/>
    <playlists>
      <playlist pid = "p1" created ="12/03/11" playcount = "5" /> 
    </playlists>
   </user>

  <user uid = "u2" dob = "06/03/95" email = "jane@hotmail.com">
    <surname> Dod</surname>
    <givennames> Jane </givennames>
    <follows who = "u1 u3"/>
    <playlists>
      <playlist pid = "p2" created ="12/02/10" playcount = "2"/> 
    </playlists>
   </user>

   <user uid = "u3" dob = "06/04/95" email = "dave@hotmail.com">
    <surname> ron</surname>
    <givennames> dave </givennames>
    <follows who = "u1 u2"/>
    <playlists>
      <playlist pid = "p3" created ="12/02/09" playcount = "9"/> 
     </playlists>
   </user>

   <user uid = "u4" dob = "06/04/99" email = "jeff@hotmail.com">
    <surname> dun</surname>
    <givennames> jeff</givennames>
     <follows who = "u1 u2 u3"/>
    <playlists>
      <playlist pid = "p4" created ="12/02/09" playcount = "3"/> 
    </playlists>
   </user>

</users>

我需要一个提供输出的查询:

<fewfollowers>
    <who uid = "u2">
           <follower uid = "u1"/>
           <follower uid = "u3"/>
           <follower uid = "u4"/>
    </who>
    <who uid = "u3">
           <follower uid = "u2"/>
           <follower uid = "u4"/>
    </who>
    <who uid = "u4">
    </who>
</fewfollowers>

!ATTLIST跟随谁IDREFS #IMPLIED

如果用户报告没有关注者,请报告自己的uid

我尝试过使用count()函数,但我没有得到任何帮助。我试试:

for $user in doc("users.xml")/users/user
   return count($user/follows/@who = $user")

但这似乎只返回每个$ user的@who计数而不是特定元素。此外,我将如何遍历IDREFS属性?它们应该被一个空格区分,但我的计数函数似乎只将它注册为1个属性而不是多个。我曾期望我的功能至少返回:

 1, 2, 2, 3

但它返回:

1,1,1,1

2 个答案:

答案 0 :(得分:0)

我同意@oldProgrammer。你不应该把ID放在一个属性中,但也许你无法控制它。如果你只是将它们放入元素中,那么你就不必将它们标记化。

您获得1,1,1,1的原因是因为您的count函数正在进行比较,它将为true或false。这将永远是1.所以我认为你的意思是在这个$user $user/follows/@who[. $user]周围加上一个谓词。虽然$user是用户元素,但也不会工作。

我认为您正在寻找的是这行代码

fn:count($user/follows/fn:tokenize(@who, ' '))

根据你给我们的xml,它会返回。

2
2
2
3

您需要标记空格中的who属性以获取关注者的计数

答案 1 :(得分:0)

假设您的DTD将@who定义为类型IDREFS,并将@uid定义为类型ID,您应该可以执行以下操作:

let $followers := idref($user/follows/@who)
return (count($followers) || string-join($followers/email, "; ")