Date:
17 Jun 2011
Category:
Development Notes
Discuss:
3 comments

Some love for XMLElement

With the upcoming release of Symphony 2.2.2 (see the thread), XMLElement has been given some love with some a couple of new methods to help make working with XMLElement easier for developers. XMLElement's biggest shortcoming previously had been the lack of methods to manipulate the children of an XMLElement, often resulting in some pretty head-slapping moments. No more, we've got five new methods to make this a breeze, getChildrenByName, removeChildAt, insertChildAt, replaceChildAt and setChildren.

Our Source

For the purposes of this quick tip, we'll use the following DOM structure.

<div>
    <h1>Hello World</h1>
    <p>Bacon ipsum dolor sit amet fatback tenderloin cow, pork belly meatloaf pig ball tip pork.</p>
    <p>Tenderloin sausage short ribs jerky, meatloaf shank spare ribs ham sirloin salami rump venison</p>
    <a href='http://baconipsum.com/'>Thanks to Bacon Ipsum</a>
</div>

Which can be built with the following

$div = new XMLElement('div');
$div->appendChild(
    new XMLElement('h1', 'Hello World')
);
$div->appendChild(
    new XMLElement('p', 'Bacon ipsum dolor sit amet fatback tenderloin cow, pork belly meatloaf pig ball tip pork.')
);
$div->appendChild(
    new XMLElement('p', 'Tenderloin sausage short ribs jerky, meatloaf shank spare ribs ham sirloin salami rump venison')
);
$div->appendChild(
    new XMLElement('a', 'Thanks to Bacon Ipsum', array('href' => 'http://baconipsum'));
);

$div->getChildrenByName($name):array

This method will return all children of a particular name in an associative array, with the key being the position of the child and the value being the XMLElement of the child.

Example

$pChildren = $div->getChildrenByName('p');

array(
    1 => XMLElement('p', 'Bacon ipsum dolor sit amet fatback tenderloin cow, pork belly meatloaf pig ball tip pork.'),
    2 => XMLElement('p', 'Tenderloin sausage short ribs jerky, meatloaf shank spare ribs ham sirloin salami rump venison')
)

$div->removeChildAt($index):boolean

This method will remove a child at a particular position, so if we wanted to remove our second paragraph, because our boss thought just one paragraph of meat was enough, we can do so easily with $div->removeChildAt(2);. Keep in mind there's no undo :) If you try to remove something that doesn't exist, the method will return false.

$div->insertChildAt($index, XMLElement $child):boolean

This method will insert a given child at a position defined by $index. If you provide an $index that is greater than the number of children, $child will be appended to the array rather than inserted at the defined $index.

Example

So you boss now wants extra meat? Fine, we'll add that after our last paragraph, but before our thank you link. You might remember $div->getChildrenByName('p') returned an array with two elements in it. The last paragraph had an index of 2 and we want this new paragraph to go in after it, so the $index will be 3. What happened to the element that was at index 3 I hear you ask? Good question. If your refer back to our original source, the thank you link was at index 3. After this function has run, it will be shuffled down to fill index 4.

$moreMeat = new XMLElement('p', 'Flank venison tenderloin shoulder.');
$div->insertChildAt(3, $moreMeat);
$pChildren = $div->getChildrenByName('p');
$children = $div->getChildren();

$pChildren returns:

array(
    1 => XMLElement('p', 'Bacon ipsum dolor sit amet fatback tenderloin cow, pork belly meatloaf pig ball tip pork.'),
    2 => XMLElement('p', 'Tenderloin sausage short ribs jerky, meatloaf shank spare ribs ham sirloin salami rump venison'),
    3 => XMLElement('p', 'Flank venison tenderloin shoulder.')
)

$children returns:

array(
    0 => XMLElement('h1', 'Hello World'),
    1 => XMLElement('p', 'Bacon ipsum dolor sit amet fatback tenderloin cow, pork belly meatloaf pig ball tip pork.'),
    2 => XMLElement('p', 'Tenderloin sausage short ribs jerky, meatloaf shank spare ribs ham sirloin salami rump venison'),
    3 => XMLElement('p', 'Flank venison tenderloin shoulder.'),
    4 => XMLElement('a', 'Thanks to Bacon Ipsum', array('href' => 'http://baconipsum'))
)

$div->replaceChildAt($index, XMLElement $child):boolean

This method will replace a child at a given $index with a new $child.

Example

You've got a new boss, they are vegetarian so want a more balanced offering.

$veganP = new XMLElement('p', 'Lotus root wattle seed kombu sorrel kakadu plum sea lettuce aubergine.');
$div->replaceChildAt(2, $veganP);
$pChildren = $div->getChildrenByName('p');

Returns

array(
    1 => XMLElement('p', 'Bacon ipsum dolor sit amet fatback tenderloin cow, pork belly meatloaf pig ball tip pork.'),
    2 => XMLElement('p', 'Lotus root wattle seed kombu sorrel kakadu plum sea lettuce aubergine.')
)

$div->setChildren(Array $children):boolean

This method will completely override the children, bypassing all 'helpers'. Use this to pass an array of XMLElement's to build your new structure.

Example

Your new boss is old school and just wants to show a 'Under Construction' page.

$h1 = new XMLElement('h1', 'Under Construction');
$p = new XMLElement('p', 'Sorry this page is under construction');

$div->setChildren(array($h1, $p));
$children = $div->getChildren();

$children returns:

array(
    0 => XMLElement('h1', 'Under Construction'),
    1 => XMLElement('p', 'Sorry this page is under construction')
)

Conclusion

There you have it five new methods, five new ways to have fun with Symphony! These methods are ready to rock and roll in the 2.2.2 Beta 1, but Symphony 2.2.2 is still in development, so if you find a bug or would like one of these methods tweaked, please let us know using Github's shiny new issue tracker. Since the release of the 2.2.2 Beta 1, replaceChildAt, insertChildAt and removeChildAt all now accept negative $index which allows you delete children relative to the end of the array instead of the start.

Comments

Brendobot™ strikes again! This is a great overview of some great changes, thanks.

Woo, this will come in handy with a project I have going. Cheers Brendan!

Anything new on this in recent!!? business mobile phone deals

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details