typescript
typescript

Reputation: 131

Using Xpath to replace href links with a string from the same parent node

I can't seem to get the right expression to modify the href links of a query result with a string (to be set as a new url) taken from another query but on the same parent node. Consider this structure:

<table>
    <tr>
        <td>
            <div class=items>
                <span class="working-link">link-1</span>
                <a href="broken-link">Item 1</a>
            </div>
        </td>
        <td>
            <div class=items>
                <span class="working-link">link-2</span>
                <a href="broken-link">Item 2</a>
            </div>
        </td>           
    </tr>
<table>

So far this is what I have come up with but with no result:

$xpath = new DomXPath($doc);
$nodeList = $xpath->query("//div[@class='items']");

foreach( $nodeList as $result) {

    $newLink = $xpath->query("//span[@class='working-link']",$result);

    foreach($result->getElementsByTagName('a') as $link) { 
    $link->setAttribute('href', $newLink);
    }

    echo $doc->saveHTML($result);
}

Upvotes: 2

Views: 937

Answers (2)

typescript
typescript

Reputation: 131

Solved! The issue here was using functions for wrong data types. It should be

$newLink =  $xpath->query("span[@class='working-link']",$result)[0];

indicating that it's an index of an array. Convert it to string after that for setAttribute to use

$link->setAttribute('href', $newLink->textContent);

Upvotes: 0

har07
har07

Reputation: 89285

Basically, you should never starts a relative XPath with / as / at the beginning of XPath always references the root document; use ./ instead. In this case span is direct child of div, so you don't need // either :

$newLink = $xpath->query("./span[@class='working-link']",$result);

or just remove the ./ completely :

$newLink = $xpath->query("span[@class='working-link']",$result);

Upvotes: 2

Related Questions