31.05.2010

SimpleXML Text und XML gemischt

Ein Teil unseres Generators verarbeitet ein XML-Template und erzeugt daraus PHP-Code.
Unsere Lösung ersetzt aber nicht nur die Platzhalter sondern hat auch Aspekte einer DSL.

Das nachfolgende Beispiel macht Probleme bei der Verarbeitung mit SimpleXML.
Der erste code-Block enthält neben dem Code-Template auch noch weitere XML-Anweisungen.

<function name='setFieldRole_[#role.name]' modifier='public'>
	<param name='value'/>
	<code>
	parent::setAttribute('Role_[#role.name]', $value);
		<foreach in='role.pk' key='' value='pk'>
			<code>
			parent::setAttribute('Role_[#role.name].[#pk.name]', $value);
			</code>
		</foreach>
	parent::store();
	</code>
</function>

Mit SimpleXML lassen sich beide verarbeiten, allerdings nur getrennt.
Der Textteil im code-Block wird so ausgegeben:

                parent::setAttribute('Role_[#role.name]', $value);
                parent::store();

Das Iterieren über die Unterknoten des code-Knotens liefert den foreach-Knoten aber ohne Positionierung im Text.
foreach wird dadurch nicht zwischen den beiden Einzelanweisungen (setAttribute(), store()) ausgeführt, sondern am Anfang oder am Ende.

Eine Lösung dieses Problems war die Verarbeitung dieser Bereiche mittels DOM, wie hier angeregt SimpleXML : Edge Conditions wurde.

Der Quelltextausschnitt dazu:

    $dom = dom_import_simplexml($xml);
    foreach($dom->childNodes as $child){
        if($child->nodeType == XML_TEXT_NODE)
            $this->writeText($child->nodeValue);
        else
            $this->proceedNode(simplexml_import_dom($child));
    }

Dieses Iterieren im DOM liefert jeden Textteil einzeln, so dass wir nach der Verarbeitung des foreach-Knotens unser gewünschtes Resultat erhalten:

parent::setAttribute('Role_[#role.name]', $value);
parent::setAttribute('Role_[#role.name].[#pk.name]', $value);
parent::store();
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

Tags: , , ,

 

Hinterlasse eine Antwort