7 Stimmen

Wie kann ich XPath verwenden, um eine Suche ohne Berücksichtigung der Groß-/Kleinschreibung durchzuführen und nicht-englische Zeichen zu unterstützen?

Ich führe eine Suche in einer XML-Datei mit folgendem Code durch:

$result = $xml->xpath("//StopPoint[contains(StopName, '$query')]");

Dabei ist $query die Suchanfrage und StopName der Name einer Bushaltestelle. Das Problem ist, dass zwischen Groß- und Kleinschreibung unterschieden wird.

Und nicht nur das, ich könnte auch mit nicht-englischen Zeichen wie ÆØÅæøå suchen, um norwegische Namen zu finden.

Wie ist das möglich?

12voto

Tomalak Punkte 320467

In XPath 1.0 (was, glaube ich, das Beste ist, was man mit PHP SimpleXML erreichen kann), müssen Sie die translate() Funktion, um eine Ausgabe in Kleinbuchstaben aus einer Eingabe in gemischter Schrift zu erzeugen.

Der Einfachheit halber würde ich es in eine Funktion wie diese verpacken:

function findStopPointByName($xml, $query) {
  $upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"; // add any characters...
  $lower = "abcdefghijklmnopqrstuvwxyzæøå"; // ...that are missing

  $arg_stopname = "translate(StopName, '$upper', '$lower')";
  $arg_query    = "translate('$query', '$upper', '$lower')";

  return $xml->xpath("//StopPoint[contains($arg_stopname, $arg_query)");
}

Als Hygienemaßnahme würde ich einfache Anführungszeichen entweder ganz verbieten oder in $query , da sie die XPath-Zeichenkette zerstören, wenn sie ignoriert werden.

10voto

vartec Punkte 124396

In XPath 2.0 können Sie lower-case() Funktion, die Unicode-fähig ist, also auch mit Nicht-ASCII-Zeichen zurechtkommt.

contains(lower-case(StopName), lower-case('$query'))

Für den Zugriff auf XPath 2.0 benötigen Sie einen XSLT 2.0 Parser. Zum Beispiel SAXON . Sie können sie aufrufen von PHP über JavaBridge.

3voto

Richard Punkte 103159

Nicht-englische Namen sollten kein Problem sein. Fügen Sie sie einfach zu Ihrem XPath hinzu. (XML ist für die Verwendung von Unicode definiert).

Was die Groß- und Kleinschreibung betrifft, ...

XPath 1.0 umfasst Folgendes Anweisung :

Zwei Zeichenfolgen sind nur dann gleich, wenn sie aus der gleichen Folge von BKS-Zeichen bestehen.

Selbst die Verwendung expliziter Prädikate für den lokalen Namen hilft also nicht weiter.

XPath 2 enthält Funktionen zur Abbildung von Groß- und Kleinschreibung. z.B. fn:Großbuchstaben


Zusätzlich: Die Verwendung der XPath-Übersetzungsfunktion sollte es ermöglichen, die Groß-/Kleinschreibung in XPath 1 zu fälschen, aber die Eingabe muss jeden Codepunkt in Groß-/Kleinschreibung enthalten, den Sie und Ihre Benutzer jemals benötigen werden:

"test" = translate($inputString, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")

0voto

bobince Punkte 512550

Darüber hinaus:

$xml->xpath("//StopPoint[enthält(StopName, '$query')]");

Sie müssen alle Apostroph-Zeichen aus $query entfernen, um zu vermeiden, dass Ihr Ausdruck bricht.

In XPath 2.0 können Sie das im Begrenzer verwendete Anführungszeichen verdoppeln, um dieses Anführungszeichen in ein Stringliteral zu setzen, aber in XPath 1.0 ist es unmöglich, den Begrenzer in den String aufzunehmen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X