Search code examples
phpxpathdomdocument

PHP DOMDocument extract elements and create new document


HTML:

<head>
    <link rel="preload" href="/_next/list.js" as="script">
    <!-- ... other link elemens -->
    <style data-styled="" data-styled-version="4.2.0"></style>
</head>

Task:

  • extract all link and style tags from head and update href attributes with host path.
  • create new html string element (piece of html) that we can output in our main html template.

PHP:

$dom = new DOMDocument();
$dom->loadHTML($stringBody);
$xpath = new DOMXPath($dom);
$headItems = $xpath->query("//head/link[@rel='preload' or @rel='stylesheet'] | //head/style");

// now I want to create html string with updated attributes, but I'm lost here..
$head = new DOMDocument();
foreach ($headItems as $headNode) {
    $headNode->setAttribute('href', $host . $headNode->getAttribute('href'));
}
$links = $head->saveHTML($headNode);
echo $links; // echo html link tags

Solution

  • Try this:

    <?php
    
    $host = 'example.com';
    
    $stringBody = '<head>
        <link rel="preload" href="/_next/list.js" as="script">
        <!-- ... other link elemens -->
        <style data-styled="" data-styled-version="4.2.0"></style>
    </head>';
    
    $dom = new DOMDocument();
    $dom->loadHTML($stringBody);
    $xpath = new DOMXPath($dom);
    $headItems = $xpath->query("//head/link[@rel='preload' or @rel='stylesheet'] | //head/style");
    
    $links = [];
    
    foreach ($headItems as $headNode) {
        if ($headNode->hasAttribute('href')) {
            $headNode->setAttribute('href', $host . $headNode->getAttribute('href'));
        }
        $links[] = $headNode->ownerDocument->saveHTML($headNode);
    }
    
    print_r($links);
    

    Output

    Array
    (
        [0] => <link rel="preload" href="example.com/_next/list.js" as="script">
        [1] => <style data-styled="" data-styled-version="4.2.0"></style>
    )