I’m using PHP DOMDocument in order to loop through an html string like this:
$htmlString = "<section>
<p>text</p>
<p>text</p>
</section>
<section>
<h2>text</h2>
<p>text</p>
<p>text</p>
</section>"
I want to replace each tag with a text value with a custom string (called $vueInterpolation), but for some reason.
ONLY the first tag of each section is getting its contents replaced!
I want all the tags inside each section to be replaced!
My method:
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$htmlString = mb_convert_encoding($htmlString, 'HTML-ENTITIES', 'UTF-8');
$dom->loadHTML($htmlString);
$count = 0;
$keyPattern = 'ccpaRights';
foreach ($dom->getElementsByTagName('section') as $section)
{
// loop through each child of <section>
foreach ($section->childNodes as $childNode)
{
$nodeValue = trim($childNode->nodeValue);
if ($nodeValue === '')
{
continue;
}
$count = $count + 1;
$key = (string) $keyPattern.'Text'.$count;
$vueInterpolation = ' {{ $t('.'"'.$key.'"'.' }} ';
$newNode = $dom->createElement($childNode->nodeName, $vueInterpolation );
$childNode->parentNode->replaceChild($newNode, $childNode);
}
}
$dom->saveHTML($dom);
$dom->save(public_path('/temp/result.html'));
Just so you know, this is the results I’m getting (notice only first tag of each section was replaced).
<section>
<p> {{ $t("ccpaRightsText1" }} </p>
<p>text</p>
</section>
<section>
<h2> {{ $t("ccpaRightsText2" }} </h2>
<p>text</p>
<p>text</p>
</section>
And this is the results I want:
<section>
<p> {{ $t("ccpaRightsText1" }} </p>
<p> {{ $t("ccpaRightsText2" }} </p>
</section>
<section>
<h2> {{ $t("ccpaRightsText3" }} </h2>
<p> {{ $t("ccpaRightsText4" }} </p>
<p> {{ $t("ccpaRightsText5" }} </p>
</section>
2
Answers
There is an error with your code because whitespaces between elements are considered nodes (#text).
So, try replace this line:
with this line:
The whole code:
UPDATED ANSWER:
I tried to use
for
loop instead offoreach
and it works. I am trying to know the reason but I can’t know it.I recommend:
Wrapping your HTML markup in a div tag so that your section tags belong to a parent element (otherwise broken results occur). Remove the temporary tags after the replacing is done.
Using XPath to target the children of the section tags.
Code: (Demo)