Du bist nicht angemeldet. Der Zugriff auf einige Boards wurde daher deaktiviert.

#1 11. Juli 2018 14:24

brandy
Server-Pate
Registriert: 05. Juni 2011
Beiträge: 799
Webseite

AJAX - Wechsel von XML auf Datenbank?

Hallo!

Ich habe mir mittels PHP, Javascript und XML eine Suche gebaut, die super funktionert.
Die XML wird automatisch aus einer CSV generiert, die der Kunde selbst er- und auf den Server stellt.

Hier der Aufbau der XML:

<?xml version="1.0" encoding="UTF-8"?>
<personal>
  <mitarbeiter>
    <Per_Nachname>Nachname#1</Per_Nachname>
    <Per_Vorname>Vorname#1</Per_Vorname>
    <Per_Titel>Mag.</Per_Titel>
    <Dst_Langbez>Institut für Wirtschaft</Dst_Langbez>
    <Dsf_Bez>Institut</Dsf_Bez>
    <Adr_SOrt>Ort#1</Adr_SOrt>
    <Adr_SStrasse>Adresse#1</Adr_SStrasse>
    <Job_Bauteil>Bauteil#1</Job_Bauteil>
    <Job_Zimmer>112</Job_Zimmer>
  </mitarbeiter>
  <mitarbeiter>
    <Per_Nachname>Nachname#1</Per_Nachname>
    <Per_Vorname>Vorname#1</Per_Vorname>
    <Per_Titel>Mag.</Per_Titel>
    <Dst_Langbez>Institut für Wirtschaft</Dst_Langbez>
    <Dsf_Bez>Institut</Dsf_Bez>
    <Adr_SOrt>Ort#1</Adr_SOrt>
    <Adr_SStrasse>Adresse#1</Adr_SStrasse>
    <Job_Bauteil>Bauteil#1</Job_Bauteil>
    <Job_Zimmer>112</Job_Zimmer>
  </mitarbeiter>
...
</personal>

Diese XML enthält ca. 919 Daten von Mitarbeitern.

Ich hab nun folgendes Problem:
Diese 919 Datensätze sind nicht unique, sondern es gibt Mitarbeiter, die z.B. viermal gespeichert werden, da sie in vier unterschiedlichen Bereichen tätig sind, die eventuell auch verschiedene Standorte haben.
Der Kunde möchte jetzt aber, dass dieser Mitarbeiter in der Suche nur einmal ausgegeben wird - aktuell wird er in der Suche ja mehrmals berücksichtigt, da er ja mehrfach gespeichert ist.
Die entsprechenden Daten, wie eben der Bereich in dem er tätig ist bzw. der Standort soll einfach kombiniert mitausgegeben werden.

Meines Erachtens wäre das jetzt eigentlich ein Auftrag für eine Datenbank - was meint ihr?
Hier wäre dann halt das Thema, dass die CSV automatisch in die Datenbank gepackt wird...
Wie sieht die Integration einer Datenbank in AJAX aus?

Vielen Dank!

Offline

#2 11. Juli 2018 16:43

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.435

Re: AJAX - Wechsel von XML auf Datenbank?

Ich verstehe die Frage nicht.

Du hast eine Suche, die via AJAX ein PHP-Script auf dem Server ausführt.
Dieses PHP-Script durchsucht eine XML-Datei und gibt das Ergebnis zurück.
Das Ergebnis enthält redundante Daten.
Ergo muss am Suchalgorithmus etwas geändert werden.
Den kenne ich allerdings nicht.

Was das jetzt mit AJAX und Datenbank zu tun hat, erschließt sich mir nicht.

Aber sei's drum ... die XML-Daten müssen erstmal in eine Datenbank importiert werden. Dazu müsste Dein PHP-Script zuerst prüfen, ob der letzte Import älter ist als das Änderungsdatum der XML-Datei. Wenn ja, dann importieren. Ansonsten Datenbank abfragen.

D.h. Du brauchst erstmal eine Datenbank. Diese Datenbank benötigt wenigstens eine Tabelle mit wenigstens einem Feld für Informationen über den letzten Import. Am einfachsten eine Tabelle mit Namen "import_info" und ein Feld namens "last_import" anlegen und dort bei jedem Import immer den aktuellen Timestamp eintragen.

Dieses Feld wird immer abgefragt, bevor die Suche beginnt, und mit dem Änderungsdatum der XML-Datei verglichen. Ist der Wert der Datei größer als der Wert in der Datenbank, dann ist die XML-Datei neuer und muss erneut import werden.

Sind die Daten in der Datenbank bzw. ist kein Import nötig, dann kann man problemlos die Datenbank abfragen und dabei redundante Daten ausschließen bzw. zusammenfassen.

Das ganze läuft allerdings auf dem Server mit Deinem PHP-Script. Nix AJAX.

Man könnte natürlich auch im Browser via Javascript, das Ergebnis entsprechend filtern, aber dazu hab ich zu wenig Informationen darüber wie das alles zusammenspielt und welche Datenformate da wie verwendet werden.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#3 12. Juli 2018 12:36

brandy
Server-Pate
Registriert: 05. Juni 2011
Beiträge: 799
Webseite

Re: AJAX - Wechsel von XML auf Datenbank?

Ok, gut - lassen wir mal die Datenbank weg und sagen wir mal ich bleibe bei dem was ich habe.

Dann kommt z.B. in der XML dieser Mitarbeiter vor:

Per_Nachname	Per_Vorname	Per_Titel	Dst_Langbez	Dsf_Bez	Adr_Sort	Adr_Sstrasse	Job_Bauteil	Job_Zimmer
Bauer	Hans	Ofr.	Institut Fahrzeugtechnik	Institut	Oberer Ort	Untere Straße 4	Haus 4	114
Bauer	Hans	Ofr.	Haustechnik	Technik	Oberer Ort	Linke Straße	Haus 2	4

Kann ich diesen per Javascript so filtern, dass er mir die zum ersten Eintrag unterschiedlichen Einträge gleich mitausgibt?

Offline

#4 12. Juli 2018 14:05

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.435

Re: AJAX - Wechsel von XML auf Datenbank?

Kann ich diesen per Javascript so filtern, dass er mir die zum ersten Eintrag unterschiedlichen Einträge gleich mitausgibt?

Die Frage kann Dir leider keiner beantworten, ohne das zugehörige Script gesehen zu haben. Prinzipiell würde ich sagen: Ja, das geht. Aber wie, dazu müsste ich wissen, welches Format die Daten haben, die als Suchergebnis vom Server zurückgegeben werden und wie das Javascript die Daten dann ins HTML-Dokument einfügt.

Der Grundgedanke ist der: Du brauchst eine Art "Schlüssel" anhand dessen Du jeden Datensatz eindeutig identifizieren kannst. Ist es möglich, dass unterschiedliche Personen die gleiche Bezeichnung "Ofr. Hans Bauer" haben? Wenn nein, dann könnte das dieser "Schlüssel" sein.

Du gehst also nach dem AJAX-Request vor dem Einfügen ins HTML-Dokument alle Datensätze durch, pappst "Per_Nachname", "Per_Vorname", und "Per_Titel" zusammen und prüfst, ob es in einem Extra-Array, schon einen Datensatz mit diesem Schlüssel gibt.

Wenn nicht, dann läuft alles wie gehabt. Zusätzlich wird dem Extra-Array der Schlüssel mit Verweis auf den aktuellen Datensatz hinzugefügt.

Wenn ja, dann kannst Du entweder den aktuellen Datensatz einfach überspringen, oder Du fügst dem bestehenden Datensatz die anderen Infos hinzu.

Soviel zur Theorie. Mit Code-Beispielen kann ich leider nicht dienen, weil zu wenig Infos.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#5 13. Juli 2018 09:24

brandy
Server-Pate
Registriert: 05. Juni 2011
Beiträge: 799
Webseite

Re: AJAX - Wechsel von XML auf Datenbank?

Hallo!

Alles in allem besteht das ganze aus 2 Dateien:

suche.php

<script>
function showResult(str) {
  if (str.length==0) {
    document.getElementById("livesearch").innerHTML="";
    document.getElementById("livesearch").style.border="0px";
    return;
  }
  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
  } else {  // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.onreadystatechange=function() {
    if (this.readyState==4 && this.status==200) {
      document.getElementById("livesearch").innerHTML=this.responseText;
    }
  }
  xmlhttp.open("GET","livesearch.php?q="+str,true);
  xmlhttp.send();
}
</script>

livesearch.php

<?php
$xmlDoc=new DOMDocument();
$xmlDoc->load("resources/output-small.xml");

$daten=$xmlDoc->getElementsByTagName('mitarbeiter');

//get the q parameter from URL
$q=$_GET["q"];

//lookup all links from the xml file if length of q>0
if (strlen($q)>0) {
  $hint="";
  for($i=0; $i<($daten->length); $i++) {
    $Per_Nachname=$daten->item($i)->getElementsByTagName('Per_Nachname');
    $Per_Vorname=$daten->item($i)->getElementsByTagName('Per_Vorname');
    $Per_Titel=$daten->item($i)->getElementsByTagName('Per_Titel');
    $Dst_Langbez=$daten->item($i)->getElementsByTagName('Dst_Langbez');
	 $Job_Bauteil=$daten->item($i)->getElementsByTagName('Job_Bauteil');
	 $Adr_SStrasse=$daten->item($i)->getElementsByTagName('Adr_SStrasse');
	 $Job_Zimmer=$daten->item($i)->getElementsByTagName('Job_Zimmer');
	 $Dsf_Bez=$daten->item($i)->getElementsByTagName('Dsf_Bez');
	 $Adr_SOrt=$daten->item($i)->getElementsByTagName('Adr_SOrt');

    if ($Per_Vorname->item(0)->nodeType==1) {
      //find a link matching the search text
      if (stristr($Per_Nachname->item(0)->childNodes->item(0)->nodeValue,$q) or stristr($Per_Vorname->item(0)->childNodes->item(0)->nodeValue,$q) or stristr($Dst_Langbez->item(0)->childNodes->item(0)->nodeValue,$q)) {
        if ($hint=="") {
          $hint="<div class=\"panel\"><div class=\"row\"><div class=\"small-10 columns\"><div class=\"name\">" . $Per_Titel->item(0)->childNodes->item(0)->nodeValue . " " . $Per_Vorname->item(0)->childNodes->item(0)->nodeValue . " " . $Per_Nachname->item(0)->childNodes->item(0)->nodeValue . "</div><div class=\"bezeichnung\">" . $Dsf_Bez->item(0)->childNodes->item(0)->nodeValue . " " . $Dst_Langbez->item(0)->childNodes->item(0)->nodeValue. "</div><br/><div class=\"abteilung\">" . $Job_Bauteil->item(0)->childNodes->item(0)->nodeValue. "</div><div class=\"standort\">" . $Adr_SStrasse->item(0)->childNodes->item(0)->nodeValue . "</div><div class=\"ort\">" . $Adr_SOrt->item(0)->childNodes->item(0)->nodeValue . "</div></div><div class=\"small-2 columns\"><div class=\"zimmer\">Zimmer:<br/><span style=\"font-size: 50px;\">" . $Job_Zimmer->item(0)->childNodes->item(0)->nodeValue . "</span></div></div></div></div>";
        } else {
          $hint=$hint . "<div class=\"panel\"><div class=\"row\"><div class=\"small-10 columns\"><div class=\"name\">" . $Per_Titel->item(0)->childNodes->item(0)->nodeValue . " " . $Per_Vorname->item(0)->childNodes->item(0)->nodeValue . " " . $Per_Nachname->item(0)->childNodes->item(0)->nodeValue . "</div><div class=\"bezeichnung\">" . $Dsf_Bez->item(0)->childNodes->item(0)->nodeValue . " " . $Dst_Langbez->item(0)->childNodes->item(0)->nodeValue . "</div><br/><div class=\"abteilung\">" . $Job_Bauteil->item(0)->childNodes->item(0)->nodeValue. "</div><div class=\"standort\">" . $Adr_SStrasse->item(0)->childNodes->item(0)->nodeValue . "</div><div class=\"ort\">" . $Adr_SOrt->item(0)->childNodes->item(0)->nodeValue . "</div></div><div class=\"small-2 columns\"><div class=\"zimmer\">Zimmer:<br/><span style=\"font-size: 50px;\">" . $Job_Zimmer->item(0)->childNodes->item(0)->nodeValue . "</span></div></div></div></div>";
        }
      }
    }
  }
}

// Set output to "no suggestion" if no hint was found
// or to the correct values
if ($hint=="") {
  $response="<span class=\"not-found\">Nichts gefunden!</span>";
} else {
  $response=$hint;
}

//output the response
echo $response;
?> 

Hilft dir das weiter?
Vielen Dank!

Offline

#6 13. Juli 2018 14:46

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.435

Re: AJAX - Wechsel von XML auf Datenbank?

Ich würde im PHP Script livesearch.php ansetzen.
Und alles umschreiben:

<?php

$searchstring = isset( $_GET[ 'q' ] ) ? trim( strtolower( $_GET[ 'q' ] ) ) : '';
$results      = [];
if( strlen( $searchstring ) )
{
	$xmlDoc = new DOMDocument();
	$xmlDoc->load( 'resources/output-small.xml' );
	
	$xmlDoc->normalizeDocument();
	$xpath = new DOMXPath( $xmlDoc );
	
	$matches = $xpath->query( "//text()[contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ','abcdefghijklmnopqrstuvwxyzäöü'),'" . $searchstring . "')]" );
	foreach( $matches as $match )
	{
		$dataset = $match->parentNode->parentNode;
		
		$key = trim( $xpath->query( 'Per_Titel' , $dataset )->item(0)->nodeValue ) . ' '
			. trim( $xpath->query( 'Per_Vorname' , $dataset )->item(0)->nodeValue ) . ' '
			. trim( $xpath->query( 'Per_Nachname' , $dataset )->item(0)->nodeValue );
		
		$output = '<div class="small-10 columns">';
		
		if( !isset( $results[ $key ] ) )
			$output .= '<div class="name">' . $key . '</div>';
		
		$output .= '<div class="bezeichnung">' 
			. trim( $xpath->query( 'Dsf_Bez' , $dataset )->item(0)->nodeValue ) . " "
			. trim( $xpath->query( 'Dst_Langbez' , $dataset )->item(0)->nodeValue )
			. '</div><div class="abteilung">' 
			. trim( $xpath->query( 'Job_Bauteil' , $dataset )->item(0)->nodeValue ) 
			. '</div><div class="standort">' 
			. trim( $xpath->query( 'Adr_SStrasse' , $dataset )->item(0)->nodeValue ) 
			. '</div><div class="ort">' 
			. trim( $xpath->query( 'Adr_SOrt' , $dataset )->item(0)->nodeValue ) 
			. '</div></div><div class="small-2 columns"><div class="zimmer">Zimmer:<br/><span style="font-size: 50px;">'
			. trim( $xpath->query( 'Job_Zimmer' , $dataset )->item(0)->nodeValue )
			. '</span></div></div>';
		
		isset( $results[ $key ] ) || $results[ $key ] = '';
		$results[ $key ] .= $output;
	}
}

if( empty( $results ) )
	echo '<span class="not-found">Nichts gefunden!</span>';
else
	echo '<div class="panel"><div class="row">' . implode( '</div></div><div class="panel"><div class="row">' , $results ) . '</div></div>';

Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#7 18. Juli 2018 10:04

brandy
Server-Pate
Registriert: 05. Juni 2011
Beiträge: 799
Webseite

Re: AJAX - Wechsel von XML auf Datenbank?

Ich hab mir den Code jetzt angeschaut.
Also er prüft jetzt ob die Felder "Per_Titel", "Per_Vorname" und "Per_Nachname" des aktuellen Datensatzes gleich dem vorhergehenden sind, oder?
Falls ja, baut er damit alles wieder zusammen:

		$output .= '<div class="bezeichnung">' 
			. trim( $xpath->query( 'Dsf_Bez' , $dataset )->item(0)->nodeValue ) . " "
			. trim( $xpath->query( 'Dst_Langbez' , $dataset )->item(0)->nodeValue )
			. '</div><div class="abteilung">' 
			. trim( $xpath->query( 'Job_Bauteil' , $dataset )->item(0)->nodeValue ) 
			. '</div><div class="standort">' 
			. trim( $xpath->query( 'Adr_SStrasse' , $dataset )->item(0)->nodeValue ) 
			. '</div><div class="ort">' 
			. trim( $xpath->query( 'Adr_SOrt' , $dataset )->item(0)->nodeValue ) 
			. '</div></div><div class="small-2 columns"><div class="zimmer">Zimmer:<br/><span style="font-size: 50px;">'
			. trim( $xpath->query( 'Job_Zimmer' , $dataset )->item(0)->nodeValue )
			. '</span></div></div>';

Was macht aber diese Zeile:

$matches = $xpath->query( "//text() contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ','abcdefghijklmnopqrstuvwxyzäöü'),'" . $searchstring . "')]" );

Vielen Dank!

Offline

#8 18. Juli 2018 11:01

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.435

Re: AJAX - Wechsel von XML auf Datenbank?

Also er prüft jetzt ob die Felder "Per_Titel", "Per_Vorname" und "Per_Nachname" des aktuellen Datensatzes gleich dem vorhergehenden sind, oder?

Nicht direkt.
Es werden zwei Variablen verwendet.

$output ist die Ausgabe des einzelnen Datensatzes.
Alle Datensätze werden bei Dir in einer Art Wrapper ausgegeben.
D.h. diesen Wert müssen wir in jedem Fall jeder Ausgabe hinzufügen:

$output = '<div class="small-10 columns">';

$results ist ein Array welches später alle $outputs beinhaltet. Als Index für dieses Array werden Titel, Vor- und Nachname eines jeden Datensatzes verwendet ($key). Existiert noch kein Eintrag mit diesem Index, wissen wir, dass Titel, Vor- und Nachname ausgegeben werden müssen. D.h. sie werden der $output-Variable einfach angehängt:

$output .= '<div class="name">' . $key . '</div>';

Anschließend werden der Ausgabe alle anderen Daten hinzugefügt.

Zum Schluss wird im Array ein Eintrag mit dem Index angelegt - falls noch nicht vorhanden - und an diesen Eintrag wird einfach die komplette Ausgabe des aktuellen Datensatzes angehängt (beim ersten mal noch mit Titel, Vor- und Nachname, ab dem zweiten nicht mehr).

D.h. die Ausgabe enthält Titel, Vor- und Nachname nur ein einziges Mal, aber ansonsten alle anderen Suchergebnisse zu diesem Namen.

Was macht aber diese Zeile:

Irgendwas mit $searchstring. Kann also nur etwas mit der Suche des gesuchten Begriffs im XML-Dokument zu tun haben wink

Anstelle alle XML-Knoten durchzugehen und deren Inhalt mit dem Suchbegriff zu vergleichen, werden hier mit einem einzigen xpath-query alle Text-Knoten zurückgegeben, die den Suchbegriff enthalten. translate() wandelt dabei alles in diesen Text-Knoten in Kleinbuchstaben um (wie auch der Suchbegriff mit strtolower() ), damit Groß- und Kleinschreibung bei der Suche nicht zum Problem wird.

(Ich finde xpath einfach cooler  cool  lol  Soll außerdem schneller sein als getElementsByBlahblah und ich muss den Namen der Elemente an dieser Stelle überhaupt nicht kennen. Wenn Du jetzt nicht so einen Spezialfall hättest, könnte man mit xpath auch eine allgemeine Suchfunktion basteln, die auf jedes X-beliebige XML-Dokument anwendbar wäre, von dem ich überhaupt nicht wissen muss, wie es aufgebaut ist - okay, ein bissel muss man das Dokument meistens schon kennen. XML ist eigentlich immer ein Spezialfall, aber mit xpath ist man i.d.R. um einiges flexibler.)


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline