peter81: Vereinfachung von PHP-Code

Hallo,

ich steh leider im Moment einwenig auf der Leitung. Ich habe folgenden Code geschrieben

for($num[0] = count($xml->positions->position), $crr[0] = 0; $crr[0] < $num[0]; $crr[0]++) {  
	$xmlLevels = 1;  
	  
	for($num[1] = count($xml->positions->position[$crr[0]]->position), $crr[1] = 0; $crr[1] < $num[1]; $crr[1]++) {  
		$xmlLevels = 2;  
		  
		for($num[2] = count($xml->positions->position[$crr[0]]->position[$crr[1]]->position), $crr[2] = 0; $crr[2] < $num[2]; $crr[2]++) {  
			$xmlLevels = 3;  
			  
			for($num[3] = count($xml->positions->position[$crr[0]]->position[$crr[1]]->position[$crr[2]]->position), $crr[3] = 0; $crr[3] < $num[3]; $crr[3]++) {  
				$xmlLevels = 4;  
				  
				//...müsste immer so weiter gehn ?!  
			}  
		}  
	}  
}

Allerdings ist das nicht wirklich sinnvoll, denn ich möchte damit checken wie viele "Level" es in der XML-Datei gibt, und nicht bereits vorher die Anzahl der eben durch die Anzahl der for-Schleifen begrenzen.
Leider komm ich selbst nicht drauf wie ich das schlauer lösen kann. Kann mir jemand helfen?

Die XML-Datei ist so aufgebaut:

<positions>
   <position>
       <position>
          ...
       </position>
   </position>

<position></position>

</positions>

Das ganze soll sich allerdings unbegrenzt verschachteln lassen.

Liebe Grüße,
Peter

  1. Moin,

    Das ganze soll sich allerdings unbegrenzt verschachteln lassen.

    Stichwort Rekursion.

    Gruß,
    Take

  2. Hallo,

    Hi,

    Allerdings ist das nicht wirklich sinnvoll, denn ich möchte damit checken wie viele "Level" es in der XML-Datei gibt, und nicht bereits vorher die Anzahl der eben durch die Anzahl der for-Schleifen begrenzen.
    Leider komm ich selbst nicht drauf wie ich das schlauer lösen kann. Kann mir jemand helfen?

    Ich hab hier mal eine (ungetestete) rekursive Lösung geschrieben:

      
    $positions = $xml->positions;  
    $positionLevels=dive($positions, 0);  
      
    function dive($position, $p) {  
    	$count = count ($position->position);  
    	if ($count>0) {  
    		$p++;  
    	}  
    	for ($pos=0;$pos<$count;$pos++) {  
    		$posi=$position->position[$pos];  
    		$a= dive($posi, $p);  
    		if ($a>$p) {  
    			$p=$a;  
    		}  
    	}  
    	return $p;  
    }  
    
    

    Isnicht ganz sauber und wie gesagt ungetestet, aber evtl hilft dir das ja weiter :)

    Gruß,
    eneR

    1. Hi!

      $count = count ($position->position);
      if ($count>0) {
      $p++;
      }

      Als Einzeiler könnte man

      $p += (bool)count($position->position);

      schreiben, aber der bool-Trick macht die Sache recht undurchsichtig. Ich wollte ja sign() nehmen, aber das kennt PHP nicht. Da die Anzahl nicht weiter benötigt wird, ist es wenig sinnvoll, sie zwischenzuspeichern. Es reicht

      if (count($position->position));
          $p++;

      Und noch besser wäre hasChildNodes(), denn es interessiert ja nicht die Anzahl, sondern nur, _ob_ welche vorhanden sind. Das ist auch (in dem Fall sicher vernachlässigbar minimal) performanter, weil nicht alle Kinder durchlaufen werden müssen, sondern nach dem ersten schon das gewünschte Ergebnis feststeht.

        $a= dive($posi, $p);  
        if ($a>$p) {  
        	$p=$a;  
      

      An welche anderen Situationen hast du denn hier gedacht? $p = dive($posi, $p); wäre doch völlig ausreichend und richtig.

      Isnicht ganz sauber und wie gesagt ungetestet, aber evtl hilft dir das ja weiter :)

      Das ist immer so eine Sache mit schnell mal hingeschriebenem Code. Vor allem, wenn er ungetestet ist. Getestet kann er natürlich auch noch Fehler enthalten, aber wenigstens die gröbsten funktionellen Schnitzer sollten dabei erkannt werden. Jedenfalls ist bei Code nicht unbedingt erkennbar, ob eine bestimmte Absicht hinter einem Konstrukt steckt und sich nur ein Fehler eingeschlichen hat, oder ob die Herangehensweise nicht zielführend ist. Besser ist es, zunächst einmal ein klaren Worten zu beschreiben, wie der Ablauf sein soll. Selbst Pseudo-Code halte ich für das Verständnis besser als kommentarlosen Code.

      Lo!

      1. Hallo,

        $p += (bool)count($position->position);

        das geht in vielen Programmiersprachen gut; es ist aber heikel, weil man sich damit auf den numerischen Wert des boolschen Ausdrucks true verlässt. Der ist in den meisten Sprachen 1; wirklich verlassen darf man sich aber nur auf !=0. Ich erinnere mich dunkel, dass ich auch schon mit älteren 16bit-Compilern zu tun hatte, in denen ein boolsches true intern durch den Zahlenwert -1 (x0FFFF) dargestellt wurde.

        Es reicht

        if (count($position->position));
            $p++;

        Nein, so bitte nicht! Ein Semikolon nach der Klammer des if-Statements, ohne dass eine Anweisung oder ein Anweisungsblock folgt, ist syntaktisch erlaubt, ergibt aber keinen Sinn und ist fast immer ein logischer Fehler.
        Anders beim Kopf einer for-Schleife: Hier ist es möglich, die Anweisungen, die den Schleifenrumpf ausmachen, stattdessen in der Klammer zu notieren, wenn sie alle als Ausdruck formulierbar sind (und keine weiteren Kontrollstrukturen enthalten). Dann kann sowas wie

        for ($i=0; $i<100; $array[$i++]=0);

        durchaus Sinn ergeben.

        So long,
         Martin

        --
        Wer morgens zerknittert aufsteht, hat den ganzen Tag Gelegenheit, sich zu entfalten.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Hi!

          $p += (bool)count($position->position);
          das geht in vielen Programmiersprachen gut; es ist aber heikel, weil man sich damit auf den numerischen Wert des boolschen Ausdrucks true verlässt.

          Ich will das ja auch nicht weiter propagieren. Unter PHP ist sie problemlos möglich, denn da sind die Werte 0 und 1 für false und true definiert. Wichtiger ist, dass sie schlecht lesbar ist und es bessere Lösungen gibt.

          Es reicht

          if (count($position->position));
              $p++;
          Nein, so bitte nicht! Ein Semikolon nach der Klammer des if-Statements, ohne dass eine Anweisung oder ein Anweisungsblock folgt, ist syntaktisch erlaubt, ergibt aber keinen Sinn und ist fast immer ein logischer Fehler.

          Copy'n'Paste-Fehler, das Semikolon sollte da natürlich gar nicht hin.

          Lo!

          1. Hi,

            Es reicht

            if (count($position->position));
                $p++;
            Nein, so bitte nicht! Ein Semikolon nach der Klammer des if-Statements, ohne dass eine Anweisung oder ein Anweisungsblock folgt, ist syntaktisch erlaubt, ergibt aber keinen Sinn und ist fast immer ein logischer Fehler.

            Copy'n'Paste-Fehler, das Semikolon sollte da natürlich gar nicht hin.

            bitte passe das nächste mal etwas besser auf! Laien kopieren sich Code und dann geht er nicht , nur weil ihr hier irgendwo Code rauskopiert und dann pastet !!! Das hier war immer ein Qualitätsforum und sollte es -meines ERachtens- auch bleiben !!!

            Leider wird hier viel Unsinn gepostet mittlerweile!! DAS war früher anders!

            viele grüße
            webphreaker V3

            1. Hi,

              Es reicht

              if (count($position->position));
                  $p++;
              Nein, so bitte nicht! Ein Semikolon nach der Klammer des if-Statements, ohne dass eine Anweisung oder ein Anweisungsblock folgt, ist syntaktisch erlaubt, ergibt aber keinen Sinn und ist fast immer ein logischer Fehler.

              Copy'n'Paste-Fehler, das Semikolon sollte da natürlich gar nicht hin.

              bitte passe das nächste mal etwas besser auf! Laien kopieren sich Code und dann geht er nicht , nur weil ihr hier irgendwo Code rauskopiert und dann pastet !!! Das hier war immer ein Qualitätsforum und sollte es -meines ERachtens- auch bleiben !!!

              Leider wird hier viel Unsinn gepostet mittlerweile!! DAS war früher anders!

              genau! Dieser Beitrag ist wirklich Unsinn!

    2. Super danke das hat mir geholfen.
      Jetzt funktioniert soweit alles.

      LG

      1. Super danke das hat mir geholfen.
        Jetzt funktioniert soweit alles.

        LG

        Der Code hat aber nicht ohne fixes funktioniert, oder? Falls doch: Würde mich SEHR stolz machen, ansonsten poste doch bitte den korrigierten Code :)

        Greez!
        P.S.: Falls du das noch zu lesen bekommst, ist ja schon ein paar Tage her :S