2009-02-20 11 views
39

Próbuję zbudować złożone wyrażenie xpath, które odpowie na następujący warunek.Wyrażenie Xpath z wieloma predykatami

Z danych XML poniżej, zwraca użytkownika podmiot, który:

  1. Jego loginname jest "user1"
  2. Nazywa się "Użytkownik 1"
  3. Ma 2 różne wartości profili: "operator" i "admin" (Nie znam Kolejność ct naprzód)

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

Może ktoś proszę podać przykład do takiej sytuacji?

EDIT: Dodano kompleks podmiot profil

Odpowiedz

64

Poniższy powinien robić to, co jesteś po:

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

Posiadanie dwóch testów dla wartości profile wartość może wydawać się dziwna, ale ponieważ istnieje wiele węzłów profile to co Warunek będzie spełniony, o ile co najmniej jeden węzeł odpowiada testowi.

Powodem można porównać profile bezpośrednio do string, choć faktycznie jest node jest to, że string-value od węzła elementem jest string-value wszystkich jego potomków sklejone, która w tym przypadku jest tylko zawartość value .

Jeśli profile zawierał więcej elementów niż value trzeba by użyć nieco bardziej skomplikowanego testu źródłowe w celu ustalenia istnienia dopasowanie profile węzła w oparciu tylko o value (to powinno działać ze zaktualizowanym pytanie):

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

Dzięki za szybkie rozwiązanie. Czy mogę używać XPATH takiego jak ten, lub może on zmienić logikę: /root/user [login = 'user1'] [name = 'User 1'] [profil [value = 'admin']] [profil [ value = 'operator']] – user41767

+2

Interesujące - nie wiedziałem, że możesz mieć wiele bloków predykatów, ale tak, wygląda na to, że to też działa. Fajnie, teraz nauczyłem się także czegoś :-) –

+0

Wiele predykatów funkcjonuje tylko jako ORAZ oczywiście rozszerzona składnia daje również LUB, ale ja wolę wielokrotność dla jasności. Możesz także zrobić to z osiami takimi jak poprzednie-rodzeństwo, ale byłoby to nieco rozwlekłe w przypadku prostego przykładu. – annakata

1

Zakładając users jest korzeniem:

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

Uważam, że masz na myśli "login" itp. (Nie "@login" itp.). Są to elementy, a nie atrybuty w oryginalnym pliku XML. ;-) – Tomalak

+0

Nie wiem o czym myślałem: P – dirkgently

6

Oto dokładniejsza odpowiedź (obecnie odpowiedź Greg Bukowej nie sprawdza stanu 3. w problemu: element user musi mieć dokładnie 2 profile dzieci):

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

Dzięki za pokazanie możliwości sprawdzenia dokładnej liczby elementów. Mimo to nadal nie odczytuję warunku 3 jako "musi mieć dokładnie 2 i (nie 3 lub więcej)". –

+0

@AloisMahdal, Pytanie brzmi: "3.He ma 2 różne wartości profili, które są" operator "i" admin "". Wyrażenie XPath w tej odpowiedzi dokładnie to sprawdza - ma profile "admin" i "operator" i nie ma trzeciego profilu. Jeśli istnieje trzecia wartość profilu, użytkownik będzie miał 3 różne wartości profilu - nie 2. –

+1

Opis stanowiska mówi, że muszę mówić po francusku i niemiecku. Jeśli mówię po francusku, niemiecku i włosku, czy się kwalifikuję? Chodzi o język angielski: nie jestem native speakerem, a nie językoznawcą, więc mogę się mylić, ale sposób, w jaki to czytam, zakładam, że jeśli nie zostanie to wyraźnie powiedziane (powiedzmy, jeśli naprawdę tego potrzebują, nie mów po włosku), listy nigdy nie są wyłączne. (Zauważ, że nie zamierzam udowadniać, że się mylisz, właśnie wskazywałem na "szarą strefę" w języku, przepraszam za pół-OT) –

0
/root/user[login='user1' and name='User 1' and profile/value='admin' and profile/value='operator' 
Powiązane problemy