Reputation: 1605
I'm trying to traverse through XML looking for a specific node and then modify its value. I want to find <identifier_value>
How can I do this? The xml below would be a string.
<?xml version="1.0"?>
<?xml-stylesheet href="catalog.xsl" type="text/xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<catalog>
<product description="Cardigan Sweater" product_image="cardigan.jpg">
<catalog_item gender="Men's">
<item_number>QWZ5671</item_number>
<price>39.95</price>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Large">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
</catalog_item>
<catalog_item gender="Women's">
<item_number>RRX9856</item_number>
<price>42.50</price>
<size description="Small">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
<identifiers>
<identifier>
<identifier_type>Test</identifier_type>
<identifier_value>000000001</identifier_value>
</identifier>
</identifiers>
</size>
<size description="Large">
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Extra Large">
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
</catalog_item>
</product>
</catalog>
Upvotes: 0
Views: 45
Reputation: 19492
PHPs DOM extension supports full Xpath 1.0 expressions.
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMxpath($document);
// fetch and modify identifier_value node
$expression = '(//catalog_item//identifiers/identifier/identifier_value[.="000000001"])[1]';
foreach ($xpath->evaluate($expression) as $identifierValueNode) {
$identifierValueNode->textContent = '000000042';
// dump to validate
var_dump($document->saveXML($identifierValueNode));
}
Output:
string(46) "<identifier_value>000000042</identifier_value>"
DOMXpath::evaluate()
can not just return node list, but scalar values:
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMxpath($document);
// get the first catalog item with the specified identifier
$expression = '(//catalog_item[.//identifiers/identifier/identifier_value="000000001"])[1]';
foreach ($xpath->evaluate($expression) as $itemNode) {
// read some scalar values
var_dump(
$xpath->evaluate('string(item_number)', $itemNode),
$xpath->evaluate('number(price)', $itemNode)
);
}
Output:
string(7) "RRX9856"
float(42.5)
Upvotes: 0
Reputation: 17630
PHP has several plugins for working with XML. I would start with one of these. One might be the SimpleXMLElement::xpath
method.
From https://www.php.net/manual/en/simplexmlelement.xpath.php
$xml = new SimpleXMLElement($xmlstring);
$result = $xml->xpath('//identifier_value[text()="value_to_find"]');
// do something with $result, perhaps modifying the value or formatting etc.
If you're taking that entire catalog (or even a portion of it) to render to a web page, you might want to consider xslt templates so that you don't have to parse the XML manually.
Upvotes: 1