PHP XML: appendChild() und zwei for-Schleifen

FrazeColder

Lt. Commander
Registriert
Okt. 2013
Beiträge
1.718
Moin zusammen,

ich komme derzeit leider nicht weiter... Und zwar möchte ich für jedes Produkt im XML File herausfinden, ob im Title oder in der URL ein bestimmtes Keyword steht. Falls dem so ist, soll ein neuer Tag in das XML eingefügt werden welches den Wert des Keywords annimmt. Aber genau da liegt mein Problem...

Ich weiß nicht wie ich das so programmieren soll, dass der checkt ob es das Keyword gibt oder nicht und wenn nicht, dass er dann einfach "Nothing" einfügen soll. Meiner Meinung nach müsste noch ein else-Zweig in die zweite for-Schleife. Allerdings weiß ich nicht was ich da rein schreiben soll in die Bedingung. Weil wenn ich einfach reinschreibe, dass es nicht im Keyword-Array ist, dann ist es ja immer Nothing, da er in der for-Schleife ja dann immer nur Keyword 0 und nicht alles checken kann.
Weil halt immer else dann eintrifft...

Und wie kann ich das dann noch einfügen zu dem Produkt?

Code:
Code:
function isContaining($searches, $titleTag, $urlTag, $productTag, $path){

    $dom = new DOMDocument('1.0', 'utf-8');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->load($path);
    $root = $dom->documentElement;

    $markerTitle = $root->getElementsByTagName($titleTag);
    $markerURL = $root->getElementsByTagName($urlTag);

    $plat = array();

    for($i = $markerTitle->length - 1; $i >= 0 ; $i--){

        $title = $markerTitle->item($i)->textContent;
        $url = $markerURL->item($i)->textContent;

        $co = count($searches);

        for($j = 0; $j < $co; $j++){
            if(stripos($title, $searches[$j]) !== false){
                if($j > 4){
                    array_push($plat, "PlayStation");
                }elseif($j < 5){
                    array_push($plat, $searches[$j]);
                }
            }elseif(stripos($url, $searches[$j]) !== false){
                if($j > 4){
                    array_push($plat, "PlayStation");
                }elseif($j < 5){
                    array_push($plat, $searches[$j]);
                }
            }elseif($j == 7 && stripos($url, $searches[$j]) == false){
                array_push($plat, "Nothing");
            }
        }
    }

    array_reverse($plat);
    print_r($plat);
    $c = count($plat);

    for($i = 0; $i < $c; $i++){
        $node = $dom->createElement('plat', $plat[$c]);
        $dom->getElementsByTagName($productTag)->item($i)->appendChild($node);
    }

MfG und Vielen Dank!
Ergänzung ()

Ich habe nun mein Problem lösen können. Das Array was ich mir erstelle und fülle mit den Werten funktioniert nun!
Es hat genau 1589 Einträge (Von 0 - 1588).

Allerdings habe ich immer noch ein Problem. Und zwar sind laut meiner Testprüfung nur 1588 Produkte und auch nur 1588 Namen in meiner XML Liste, was ich leider nicht verstehe... Wieso ist das Array größer?
Dardurch kommt es dann zu dieser Fehlermeldung:
HP Notice: Undefined offset: 1589 in C:\Users\Jan\PhpstormProjects\censored\test.php on line 63
PHP Fatal error: Uncaught Error: Call to a member function appendChild() on null in C:\Users\Jan\PhpstormProjectscensored\test.php:64
Stack trace:
#0 C:\Users\Jan\PhpstormProjects\censored\test.php(95): isContaining(Array, 'name', 'link', 'product', 'data/gamesplane...')
#1 {main}
thrown in C:\Users\Jan\PhpstormProjects\censored\test.php on line 64

Hat jemand eine Idee, wie ich das beheben kann?
Line 64 ist in dem Code hier Line 48!

Der Code sind nun so aus:
Code:
function isContaining($searches, $titleTag, $urlTag, $productTag, $path){

    $dom = new DOMDocument('1.0', 'utf-8');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->load($path);
    $root = $dom->documentElement;

    $markerTitle = $root->getElementsByTagName($titleTag);
    $markerURL = $root->getElementsByTagName($urlTag);

    $plat = array();

    for($i = $markerTitle->length - 1; $i >= 0 ; $i--){

        $title = $markerTitle->item($i)->textContent;
        $url = $markerURL->item($i)->textContent;

        $co = count($searches);
        $productFound = false;
                for($j = 0; $j < $co; $j++){
            if(stripos($title, $searches[$j]) !== false){
                if($j > 3){
                    array_push($plat, "PlayStation");
                }else{
                    array_push($plat, $searches[$j]);
                }
                $productFound = true;
            }elseif(stripos($url, $searches[$j]) !== false){
                if($j > 3){
                    array_push($plat, "PlayStation");
                }else{
                    array_push($plat, $searches[$j]);
                }
                $productFound = true;
            }
        }
        if($productFound == false){
            array_push($plat, "Nothing");
        }
    }

    print_r($plat);
    $c = count($plat);
    echo $c;

    for($i = $c - 1; $i >= 0; $i--){
        $node = $dom->createElement('plat', $plat[$c]);
        $dom->getElementsByTagName($productTag)->item($i)->appendChild($node);
    }


    $dom->saveXML();
    $dom->save('data/gamesplanet2.xml');
}


$dom = new DOMDocument('1.0', 'utf-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load($gamesplanetPath);
$root = $dom->documentElement;

$productCounter = 0;
$nameCounter = 0;

$markerProduct = $root->getElementsByTagName("product");
for($i = $markerProduct->length - 1; $i >= 0; $i--){
    $productCounter = $productCounter + 1;
}

$markerTitle = $root->getElementsByTagName("name");
for($i = 0; $i < $markerTitle->length; $i++){
    $nameCounter = $nameCounter + 1;
}

echo $productCounter . "\n";
echo $nameCounter . "\n";

isContaining($searches, "name", "link", "product", $gamesplanetPath);

?>
 
Zu deiner Fehlermeldung:
Code:
$node = $dom->createElement('plat', $plat[$c]);
(Zeile 48)

Das geht so nicht, weil $plat[$c] in deinem Beispielfall $plat[1589] bedeutet... und du in deinem Fall daher eher $plat[$c-1] schreiben möchtest.
 
Aber sage ich das nicht schon so in Zeile 1 hier? - Mit dem Kopf der Schleife?

Code:
for($i = $c - 1; $i >= 0; $i--){
        $node = $dom->createElement('plat', $plat[$c]);
        $dom->getElementsByTagName($productTag)->item($i)->appendChild($node);
    }
 
$i = $c - 1

Das ändert ja nichts an $c.

Und mit $plat[$c] kriegst du das Element an Index $c, nicht $i.
 
Ahhh... da mein Fehler... Ich muss natürlich den Zähler einbauen. Sprich, diese Lösung müsste auch gehen:

Code:
$plat[$i]
 
$c ist btw. eine sehr schlechte Wahl für einen Variablennamen.

$i, $j, ... sind gebräuchlich als Schleifenindizes, aber $c - ein $count (wenn das syntaktisch geht) oder ein $plat_length / $platLength wären vermutlich besser geeignet, und hätten auch leichter erkennen lassen, dass das $plat[$c] falsch war.
 
FrazeColder schrieb:
Moin zusammen,

ich komme derzeit leider nicht weiter...
Hast Du nicht mal Bock Dir das Buch PHP for Dummies reinzuziehn? Dann musst Du nicht wegen jeder Kleinigkeit hier im Forum aufschlagen.

Gruß
A.
 
Ich kann Java. Bin derzeit dabei mir PHP selber bei zu bringen.
Ergänzung ()

Also ich weiß wirklich nicht wo hier der Wurm drin ist... Aber selbst mit der korrigierten Schleife geht das nicht...???

Code:
    for($i = 0; $i < $sizeOfPlat; $i++){
        $node = $dom->createElement('plat', $plat[$i]);
        $dom->getElementsByTagName($productTag)->item($i)->appendChild($node);
    }
 
Hier mit als xpath Variante, die ich dir schon mal per PM geschickt habe.

Code:
function isContaining($searches, $tagNames, $path)
{
  $dom = new DOMDocument('1.0', 'utf-8');
  $dom->preserveWhiteSpace = false;
  $dom->formatOutput = true;
  $dom->load($path);

  $doc = simplexml_import_dom($dom);

  if (!is_array($tagNames)) {
    $tagNames = [$tagNames];
  }
  if (!is_array($searches)) {
    $searches = [$searches];
  }

  $items = $doc->xpath('//' . implode('|//', $tagNames));
  foreach ($items as $item) {
    $node = dom_import_simplexml($item);
    foreach ($searches as $term) {

      if (stripos($node->textContent, $term) !== false) {
        $text = $term;
      } else {
        $text = 'Nothing';
      }

      if ($node->parentNode->getElementsByTagName('plat')->length === 0) {
        $newNode = $dom->createElement('plat', $text);
        $node->parentNode->appendChild($newNode);
      }
    }
  }
  $dom->saveXML();
  $dom->save('data/gamesplanet2.xml');
}

Code:
isContaining(['PlayStation', 'PC', 'Mac'], ['name', 'link']);
 
Zurück
Oben