2009-02-20 63 views
39

我想构建一个复杂的xpath表达式,它将回答以下情况。带有多个谓词的Xpath表达式

从下面的XML数据,返回用户实体,其中:

  1. 他的登录名是 “USER1
  2. 他的名字是 “用户1
  3. 他有2个不同的配置文件值是“运营商”和“管理”(我不知道实例提前CT顺序)

    <user> 
        <login>user1</login> 
        <name>User 1</name> 
        <profile> 
        <value>admin</value> 
        <id>2</id> 
        <description>admin users</description> 
        </profile> 
        <profile> 
        <value>operator</value> 
        <id>1</id> 
        <description>Operator</description> 
        </profile> 
    </user> 
    
    <user> 
        <login>user2</login> 
        <name>User 2</name> 
        <profile> 
        <value>admin</value> 
        <id>4</id> 
        <description>admins users</description> 
        </profile> 
        <profile> 
        <value>poweruser</value> 
        <id>5</id> 
        <description>power users</description> 
        </profile> 
    </user> 
    
    </root> 
    

是否有人可以提供一个例子这样的情况?

编辑:添加一个复杂轮廓实体

回答

64

以下应该做你以后:

/root/user[login='user1' and 
      name='User 1' and 
      profile='admin' and 
      profile='operator'] 

有两个测试对于profile值可能看起来很奇怪,但由于有多个profile节点,那么co只要至少有一个节点符合测试条件,测试就会得到满足。

您可以直接比较profilestring,即使它实际上是一个node的原因是,一个元素节点的string-value是其所有后代串联在一起,在这种情况下是value只是内容的string-value

如果profile余载value更多的元素,你不得不使用稍微复杂的谓词测试来确定基于刚刚上value(这应该与你的更新问题的工作)匹配的profile节点的存在:

/root/user[login='user1' and 
      name='User 1' and 
      profile[value='admin'] and 
      profile[value='operator']] 
+3

感谢您的快速解决方案。 我可以使用这样一个XPATH,或者它可以改变逻辑: /root/user [login ='user1'] [name ='User 1'] [profile [value ='admin']] [profile [值='操作员']] – user41767 2009-02-20 09:07:49

1

假设users是根:

/users/user[login='user1' and name='User 1' 
      and (profile='admin' and profile='operator')] 
+0

我相信你的意思是“登录”等(而不是“@login”等)。这些是元素,而不是原始XML中的属性。 ;-) – Tomalak 2009-02-20 08:41:37

+0

不知道我在想什么:P – dirkgently 2009-02-20 09:19:00

6

这里是一个更确切的答案(目前格雷格榉木的回答并不在问题检查条件3:在user元素必须恰好有2 profile小孩):

/*/user 
     [login='user1' 
     and    
     name='User 1' 
     and 
     not(profile[3]) 
     and   
     profile/value='admin' 
     and   
     profile/value='operator' 
     ] 
0
/root/user[login='user1' and name='User 1' and profile/value='admin' and profile/value='operator'