Question

Here is a snippet of the XML structure:

<product category="Desktop">
<name> Desktop 1 (d)</name>
<shipping cost="10.00" carrier="UPS" />
</product>

<product category="Tablet">
<name>Tablet 1(t)</name>
<shipping cost="0" carrier="Fed Ex" />
</product>

Using XMLReader with XPATH, I am trying to get the values of certain XML element attributes

$reader = new XMLReader;
$reader->open('products.xml');
$dom = new DOMDocument;
$xpath = new DOMXpath($dom);

while ($reader->read() && $reader->name !== 'product') {
continue;
}
while ($reader->name === 'product') {
$node = $dom->importNode($reader->expand(), TRUE);

When there is only one attribute in the XML element (e.g. <product category="Desktop">), this works fine:

$category = $xpath->evaluate('string(@category)', $node);

But when there are multiple attributes in an XML element (IE ), this is not working:

$shippingCarrier = $xpath->evaluate('string(/shipping[@cost])', $node);
$shippingCost = $xpath->evaluate('string(/shipping[@carrier])', $node);

echo "Category: " . $category . ". ";
echo "Shipping Carrier: " . $shippingCarrier . ". ";
echo "Shipping Cast: " . $shippingCost . ". ";
}
$reader->next('product');
}

Any advice? Thanks!

Was it helpful?

Solution

The expression:

shipping[@cost]

will return a <shipping> element (node), not any attribute string. The [...] is a predicate which is used to select a certain node. It says: "select the shipping element which contains a cost attribute". So you are actually selecting the same node in both expressions.

Since you only have one shipping element in your $node context don't need any predicates.

To actually select an attribute you need to add an extra step:

shipping/@cost
shipping/@carrier
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top