Maurice
Maurice

Reputation: 1092

xPath select attribute based on other attribute's value

I'm struggling with xPath for a while now and i thought i'd got the hang of it until now.

The strange thing is that if i test my pattern online it works, but when i run it locally it doesn't

I have the following XML

<Products>
    <Product>
        <Property Title="Toy" Text="Car" />
    </Product>
</Products>

Now i want to replace all Car values with Bal so i came up with something like this:

$xml_src = 'feed.xml';
$document = new DOMDocument();
$document->load($xml_src);
$xpath = new DOMXpath($document);

foreach($xpath->evaluate('//Property[@Title="Toy"]/@Text') as $text){
        $text->data = str_replace('Car', 'Bal', $text->data);
}
echo $document->saveXml();

But that doesn't do anything (i just get the whole feed with the original values), while the xPath pattern works on the site i mentioned above. I don't have a clue why

Upvotes: 1

Views: 570

Answers (2)

ThW
ThW

Reputation: 19512

Your Xpath expression returns DOMAttr nodes. You will have to manipulate the $value property.

foreach($xpath->evaluate('//Property[@Title="Toy"]/@Text') as $text) {
   $text->value = str_replace('Car', 'Bal', $text->value);
}
echo $document->saveXml();

A DOMAttr has a single child node that is a DOMText representing its value, but I don't think it is possible to address it with Xpath. Text nodes would be instances of DOMText, they would have a $data property.

Upvotes: 1

VolkerK
VolkerK

Reputation: 96189

You'd have to manuipulate the DOM, not just the representation, which in this case means using DOMElement::setAttribute

foreach($xpath->evaluate('//Property[@Title="Toy"]') as $elProperty) {
    $elProperty->setAttribute(
        'Text',
        str_replace(
            'Car',
            'Bal',
            $elProperty->getAttribute('Text')
        )
    );
}

Upvotes: 0

Related Questions