XPath: jak wybrać elementy na podstawie ich wartości?

Jestem nowy w używaniu XPath i może to być podstawowe pytanie. Prosimy o cierpliwość i pomoc w rozwiązaniu problemu. Mam taki plik XML:

<RootNode>
  <FirstChild>
    <Element attribute1="abc" attribute2="xyz">Data</Element>
  <FirstChild>
</RootNode>

Mogę potwierdzić obecność znacznika <Element> za pomocą:

//Element[@attribute1="abc" and @attribute2="xyz"]

Teraz chcę również sprawdzić wartość znacznika dla string "Data". W tym celu kazano mi użyć:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

Kiedy używam późniejszego wyrażenia, dostaję następujący błąd:

Komunikat o niepowodzeniu twierdzenia: brak dopasowanych węzłów //Element[@attribute1="abc" and @attribute2="xyz" and Data]

Uprzejmie udziel mi porady, czy wyrażenie XPath, którego użyłem, jest poprawne. Jeśli nie, jakie będzie poprawne wyrażenie XPath?

 189
Author: John Topley, 2009-07-29

2 answers

Warunek poniżej:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

Sprawdza istnienie danych elementu w elemencie, a nie dla danych wartości elementu.

Zamiast tego możesz użyć

//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]
 284
Author: Rashmi Pandit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-29 06:43:16
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]

Powodem, dla którego dodaję tę odpowiedź jest to, że chcę wyjaśnić związek . i text().

Pierwszą rzeczą jest użycie [], istnieją tylko dwa typy danych:

  1. *[number] aby wybrać węzeł z zestawu węzłów
  2. *[bool] aby odfiltrować node-set z node-set

W tym przypadku wartość jest obliczana na wartość logiczną przez funkcję boolean() i istnieje reguła:

Filtry są zawsze oceniane w odniesieniu do kontekst.

Kiedy musisz porównać text() lub . z łańcuchem znaków "Data", najpierw używa funkcji string() do przekształcenia ich w typ Łańcuchowy, a następnie otrzymuje wynik logiczny.

Istnieją dwie ważne zasady dotyczące string():

  1. Funkcja string() konwertuje zestaw węzłów na łańcuch znaków, zwracając wartość pierwszego węzła w zestawie węzłów, co w niektórych przypadkach może przynieść nieoczekiwane wyniki.

    text() jest ścieżką względną zwracającą zestaw węzłów zawiera cały węzeł tekstowy bieżącego węzła (węzeł kontekstowy), jak ["Data"]. Gdy jest oceniany przez string(["Data"]), zwróci pierwszy węzeł zestawu węzłów, więc otrzymasz "dane" tylko wtedy, gdy jest tylko jeden węzeł tekstowy w zestawie węzłów.

  2. Jeśli chcesz, aby funkcja string() łączyła cały tekst potomny, musisz przekazać pojedynczy węzeł zamiast zestawu węzłów.

    Na przykład, otrzymujemy node-set ['a', 'b'], można przekazać tam węzeł nadrzędny do string(parent), to zwróci 'ab', a z przyczyny string(.) w Twoim przypadku zwróci skonkatenowany łańcuch "Data".

Obie strony otrzymają ten sam wynik tylko wtedy, gdy jest węzeł tekstowy.

 11
Author: 宏杰李,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-14 21:28:20