I have several identical elements with different attributes that I\'m accessing with SimpleXML:
To remove/keep nodes with certain attribute value or falling into array of attribute values you can extend SimpleXMLElement
class like this (most recent version in my GitHub Gist):
class SimpleXMLElementExtended extends SimpleXMLElement
{
/**
* Removes or keeps nodes with given attributes
*
* @param string $attributeName
* @param array $attributeValues
* @param bool $keep TRUE keeps nodes and removes the rest, FALSE removes nodes and keeps the rest
* @return integer Number o affected nodes
*
* @example: $xml->o->filterAttribute('id', $products_ids); // Keeps only nodes with id attr in $products_ids
* @see: http://stackoverflow.com/questions/17185959/simplexml-remove-nodes
*/
public function filterAttribute($attributeName = '', $attributeValues = array(), $keepNodes = TRUE)
{
$nodesToRemove = array();
foreach($this as $node)
{
$attributeValue = (string)$node[$attributeName];
if ($keepNodes)
{
if (!in_array($attributeValue, $attributeValues)) $nodesToRemove[] = $node;
}
else
{
if (in_array($attributeValue, $attributeValues)) $nodesToRemove[] = $node;
}
}
$result = count($nodesToRemove);
foreach ($nodesToRemove as $node) {
unset($node[0]);
}
return $result;
}
}
Then having your $doc
XML you can remove your
node calling:
$data='
';
$doc=new SimpleXMLElementExtended($data);
$doc->seg->filterAttribute('id', ['A12'], FALSE);
or remove multiple
nodes:
$doc->seg->filterAttribute('id', ['A1', 'A12', 'A29'], FALSE);
For keeping only
and
nodes and removing the rest:
$doc->seg->filterAttribute('id', ['A5', 'A30'], TRUE);