0

In a nutshell, I'm wondering just how this can be done, since there doesn't (As far as I know) seem to be a way to do this with PHP's SimpleXMLObject setup.

Here's my xml:

<main> <item><field>1</field></item> <item><field>2</field></item> <item><field>2</field></item> <item><field>4</field></item> </main> 

I'm trying to have it so that only enteries that match the field value of 2 would be returned in a new xml object. The problem is being able to filter out what doesn't match. I've tried using unset, but it only seems to return an object with t and e as enteries. Is there a better solution for what seems to be a simple request?

6
  • See also : stackoverflow.com/questions/1153697/php-delete-xml-element Commented Sep 12, 2013 at 15:44
  • @Kethryweryn not completely. That referred with filtering based upon attribute, as opposed to filtering out entire rows based upon content in string x. At least that's what I got out of it. Commented Sep 12, 2013 at 16:42
  • You're right, read too fast. However, the DOM seems to be a good starting point for your problem ! Commented Sep 12, 2013 at 16:46
  • @Kethryweryn no worries. I wish the XML feed I dealt with had attributes, would make things so much easier. Commented Sep 12, 2013 at 16:50
  • 1
    Oops, didn't read carefully - you want to delete everything except 2. The change is pretty obvious: /main/item[field!=2]. Commented Sep 12, 2013 at 20:11

2 Answers 2

1

This seems to do the trick :

$xml = new SimpleXMLElement("<main><item><field>1</field></item><item><field>2</field></item><item><field>2</field></item><item><field>4</field></item></main>"); $xpath = $xml->xpath('/main/item'); // Comment from IMSoP : you could add the test here with /main/item[field!=2] instead of doing it later on. foreach($xpath as $seg) { if($seg->field != 2) { $dom=dom_import_simplexml($seg); $dom->parentNode->removeChild($dom); } } echo $xml->asXML(); 

Outputs :

<main> <item> <field>2</field> </item> <item> <field>2</field> </item> </main> 
Sign up to request clarification or add additional context in comments.

2 Comments

If you're going to use XPath anyway, you can avoid the if statement by building a filter into your XPath expression: /main/item[field!=2]. [Rest of comment retracted: the xpath is necessary, as you need a simple array of nodes to delete; the iterator used in foreach ( $xml->item as $seg ) doesn't like having its items removed mid-loop]
Good point. Adding in the code comments.
0

If I remember correctly, you can't delete node.

I solved this by rebuilding SimpleXMLElement object without deleted value - operations on array etc.

Try to iterate nodes, check value and when you want keep this object, copy to another SimpleXML object. It's not pretty but It can work.

Other way is use SimpleXML::asXML() to get XML code and modify it with preg_replace, but it's again not pretty... maybe use full XML DOM?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.