PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PHP: Alle HTML Tags an bestimmter Stelle schließen und wieder öffnen


Kinman
2009-01-23, 21:34:49
Hallo, ich stehe vor einem Problem. Ich habe einen String, der mit (validen) HTML Code gefüllt ist. Jetzt möchte ich an einer bestimmten Stelle im Code alle noch offenen Tags schließen und vorallem anschließend wieder öffnen. Inklusive aller Attribute.
Kennt jemand irgend ein Stückchen PHP Code oder eventuell einen RegEx (wenns damit überhaupt möglich ist), was das für mich erledigen würde? Sonst muss ich mich wohl selbst daran machen.

EDIT: Hier gelöst (http://www.forum-3dcenter.org/vbulletin/showthread.php?p=7060014#post7060014)

Kleines Beispiel:

Inhalt des Strings:

<div class="myclass">
<span style="color: red;">Hier steht <strong>fetter</strong> <span style="color: red;">Text,
<!--pagebreak-->
welcher auch noch rot ist</span>
</div>


Sollte anschließen in folgenden String resultieren

<div class="myclass">
<span style="color: red;">Hier steht <strong>fetter</strong> <span style="color: red;">Text,</span>
<div>
<!--pagebreak-->
<div class="myclass">
<span style="color: red;">welcher auch noch rot ist</span>
</div>


Einrückung ist egal. Wenn der String in ein Array von Strings, welches immer bei <!--pagebreak--> gesplittet wurde resultiert, sollte mir das auch recht sein.
Ich kann auf PHP5 und somit auf die DOM API zurückgreifen.

Danke, mfg Kinman

samm
2009-01-23, 22:37:41
Pushe z.B. die öffnenden Tags auf einen stack (array) und poppe sie (;)) wieder, wenn ein schliessender Tag vorhanden ist, bis <!-- pagebreak-->. Dann benutze den stack als Liste (array) und füge die vorhandenen öffnenden Tags der Reihe nach wieder ein.

Kinman
2009-01-23, 22:58:59
Sehr gute Idee, danke!
Ich werde das mal umsetzen ;)

Wenn jemand trotzdem noch was fertiges kennt - ich bin weiterhin interessiert. Eventuell gibt es noch andere Ansätze bzw. besser Lösungen als meine wird

mfg Kinman

Kinman
2009-01-24, 00:49:55
So, fertig.
Ist zwar sicher nicht die beste Möglichkeitm reicht aber für meine Bedürfnisse

Der übergebene HTML Code muss valide Verschachtelt sein. Folgendes würde Fehler verursachen und darf (noch) nicht vorkommen:


<div><p>Text</div></p>


Parameter:
$str HTML Code der "aufgeteilt" werden soll
$tags Durch Strichpunkt getrennte HTML Tags, welche unterbrochen werden dürfen
$breakTag Zeichenkette, welche den Umbruch bezeichnet

Zurückgegeben wird ein Array welche alle Teile des HTML Codes beinhaltet.


function pageBreak($str, $tags, $breakTag)
{
/* 2009 by PREViSiON | Sorko Jürgen */
//Prepare tags
$tags = explode(';', $tags);
$tagMatchStr = implode('|', $tags);

//Split html code
$segments = explode($breakTag, $str);

$open_elements = array();

for ($i = 0; $i < count($segments); $i++)
{
//Get all tags in the html chunk
preg_match_all("%\</?($tagMatchStr)(.*)\>%iUs", $segments[$i], $elements);
$elements = $elements[0];

//Build stack
foreach($elements as $element)
{
if (substr($element, 1, 1) != '/') array_push($open_elements, $element); //Add element
else array_pop($open_elements); //Remove element

}

//Add opening and close tags to the html chunks
$open_str = '';
$close_str = '';
$count = count($open_elements);

for($j = 0; $j < $count; $j++)
{
$open_str .= $open_elements[$j];
$close_element = $open_elements[$count - ($j + 1)];

foreach($tags as $tag)
{
if (substr($close_element, 1, strlen($tag)) == $tag) $close_str .= '</' . $tag . '>';
}
}

$segments[$i] .= $close_str;
if (isset($segments[$i + 1])) $segments[$i + 1] = $open_str . $segments[$i + 1];
}

return $segments;
}


Hier ein Beispiel:


$html = '<p style="color: green;">
<strong>Hier steht fetter <span style="color: red;">roter Text</span>,
<!--pagebreak-->
wobei der Rest grün ist</strong>
<!--pagebreak-->
Und weiter gehts auf der dritten Seite. Aber nicht mehr fett.
</p>';

echo("Original:<br />\n" . $html . "\n\n");


$segments = pageBreak($html, 'div;p;span;blockquote', '<!--pagebreak-->');
echo("Paged:<br />\n");
foreach($segments as $key => $segment) echo("\n" . $segment . "<hr />\n\n");



Solltet ihr den Code verwenden wollen oder einfach nur überarbeitet, würde es mich freuen, wenn ihr mir das Bescheid gebt (entweder per PN oder hier kurz posten).

Danke, mfg Kinman