特定の属性値を持つノードまたは属性値の配列に該当するノードを削除/保持するには、次のようにクラスを拡張できます(私のGitHub GistSimpleXMLElement
の最新バージョン):
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;
}
}
次に、$doc
XML を使用して、<seg id="A12"/>
ノードの呼び出しを削除できます。
$data='<data>
<seg id="A1"/>
<seg id="A5"/>
<seg id="A12"/>
<seg id="A29"/>
<seg id="A30"/>
</data>';
$doc=new SimpleXMLElementExtended($data);
$doc->seg->filterAttribute('id', ['A12'], FALSE);
または複数の<seg />
ノードを削除します。
$doc->seg->filterAttribute('id', ['A1', 'A12', 'A29'], FALSE);
<seg id="A5"/>
ノードとノードのみを保持<seg id="A30"/>
し、残りを削除するには:
$doc->seg->filterAttribute('id', ['A5', 'A30'], TRUE);