Node

Die Node Klasse bietet die Verwaltung von Eltern-/Kindobjekten in einer klassischen Baumstruktur. Im wesentlichen besteht eine Node aus den eigenen Daten und einer Liste der Kinder.

Eine Node hat einen Namen und einen Wert.

// Neue Node erstellen
$node=new \Alvine\Types\Node('nodeName', 'nodeValue');

echo "Name: ".$node->getName()." // Wert: ".$node->getValue()."\n";
// -> Name: nodeName // Wert: nodeValue

Manipulation der Kinder

Einer Node können Kinder hinzugefügt werden.

// Neue Node erstellen
$node=new \Alvine\Types\Node('test', 'content');

// Kinder hinzufügen
$node->appendChild(new \Alvine\Types\Node('child1', '1'));
$node->appendChild(new \Alvine\Types\Node('child2', '2'));
$node->appendChild(new \Alvine\Types\Node('child3', '3'));

Über verschiedene Funktionen kann die Liste der Kinder manipuliert werden. Dazu gehören neben dem Hinzufügen Node::appendChild(), das Auslesen Node::getChildren(), das Ersetzen von Nodes Node::replaceChildren() auch das Löschen von Nodes Node::removeChild().

Mittels Node::truncate() werden alle Kinder entfernt.

Zugriff auf die Kinder

Auf die Nodes kann mit der funktion Node::getChildren($name) zugegriffen werden. Über den Parameter $name kann eine Einschränkung auf bestimmte Tags gemacht werden.

// Neue Node erstellen
$node=new \Alvine\Types\Node('test', 'content');

// Kinder hinzufügen
$node->appendChild(new \Alvine\Types\Node('childA', '1'));
$node->appendChild(new \Alvine\Types\Node('childB', '2'));
$node->appendChild(new \Alvine\Types\Node('childC', '3'));
$node->appendChild(new \Alvine\Types\Node('childC', '4'));
$node->appendChild(new \Alvine\Types\Node('childD', '5'));

// Alle Nodes mit childC selektieren
$nodes=$node->getChildren('childC');
foreach($nodes AS $node) {
    echo (string) $node."\n";
}
// -> 3
// -> 4

Alternativer Zugriff

Über die in PHP implementierten magische Setter __set- und Getter __get-Methode kann direkt auf ein Kind zugegriffen werden.

// Neue Node erstellen
$node=new \Alvine\Types\Node('test', 'content');

// Kinder hinzufügen
$node->appendChild(new \Alvine\Types\Node('child1', '1'));
$node->appendChild(new \Alvine\Types\Node('child2', '2'));
$node->appendChild(new \Alvine\Types\Node('child3', '3'));


echo $node->child1;
// -> 1

echo $node->child3;
// -> 3

Iteratoren

Die Node-Klasse implementiert neben dem ArrayAccess-Interface auch die folgenden Iterator-Interfaces: Iterator, RecursiveIterator, OuterIterator. Damit lässt sich einfach auf die Baumstruktur zugreifen.

In dem folgenden Beispiel wird eine Baumstruktur aufgebaut und mittels einem rekursiven Iterator durch die Struktur gelaufen.

/**
 * Gegebene Node-Struktur
 * 
 * node1
 *  ├─ node2
 *  │    ├─ node3
 *  │    │    └─ node4
 *  │    │         ├─ node6
 *  │    │         └─ node7
 *  │    └─ node5
 *  ├─ node8
 *  ├─ node9
 **/


// Erstellen der einzelnen Node-Objekte
$n1=new \Alvine\Types\Node('node1', 'i1');
$n2=new \Alvine\Types\Node('node2', 'i2');
$n3=new \Alvine\Types\Node('node3', 'i3');
$n4=new \Alvine\Types\Node('node4', 'i4');
$n5=new \Alvine\Types\Node('node5', 'i5');
$n6=new \Alvine\Types\Node('node6', 'i6');
$n7=new \Alvine\Types\Node('node7', 'i7');
$n8=new \Alvine\Types\Node('node8', 'i8');
$n9=new \Alvine\Types\Node('node9', 'i9');

// Aufbau der Baumstruktur
$n1->appendChild(
        $n2->appendChild(
            $n3->appendChild(
                $n4->appendChild($n6)
                ->appendChild($n7)))
        ->appendChild($n5))
    ->appendChild($n8)
    ->appendChild($n9);

// Erstellen des Iterator
$iteratorIterator=new \RecursiveIteratorIterator(
    $n1->getChildren(),
    \RecursiveIteratorIterator::SELF_FIRST,
    \RecursiveIteratorIterator::CATCH_GET_CHILD);

// Iterator durchlaufen
foreach($iteratorIterator as $node) {
    echo (string) \str_pad($node->getName(), 5+$node->getLevel(), '.', \STR_PAD_LEFT)." (Level: ".$node->getLevel().") \n";
}

/**
 * ->
 * .node2 (Level: 1) 
 * ..node3 (Level: 2) 
 * ...node4 (Level: 3) 
 * ....node6 (Level: 4) 
 * ....node7 (Level: 4) 
 * ..node5 (Level: 2) 
 * .node8 (Level: 1) 
 * .node9 (Level: 1)
 */

Nodes suchen

Über Constraints lassen sich die Kinder einer Node durchsuchen. Das Ergebnis der Suche ist eine (nodelist.md)[NodeList].

// Neue Node erstellen
$node=new \Alvine\Types\Node('test', 'content');

$div=new Alvine\Types\Node('id1', 'value1');
$div->appendChild(new Alvine\Types\Node('id2', 'value2'));
$div->appendChild(new Alvine\Types\Node('id3', 'value3'));
$div->appendChild(new Alvine\Types\Node('id3', 'value4'));

// Suche nach einem Namen
$find1=$div->find(new Alvine\Types\Node\Constraint\Name('id3'));
foreach($find1 AS $n) {
    echo $n->getName()." :: ".$n->getValue()." \n";
}
// -> id3 :: value3 
// -> id3 :: value4 

// Suche nach einem Wert und einem Namen
$find2=$div->find(new \Alvine\Util\Constraint\AndOperator(
        new \Alvine\Types\Node\Constraint\Name('id3'),
        new \Alvine\Types\Node\Constraint\Value('value4')
    ));
foreach($find2 AS $n) {
    echo $n->getName()." :: ".$n->getValue()." \n";
}
// -> id3 :: value4 

// Suche nach einem Wert alleine
$find3=$div->find(new \Alvine\Types\Node\Constraint\Value('value2'));
foreach($find3 AS $n) {
    echo $n->getName()." :: ".$n->getValue()." \n";
}
// -> id2 :: value2