views:

155

answers:

2

I am defining the elements of form in a simple XML structure like so:

<subtab id="page_background" label="Page Background" prefix="page">
   <input label="Background color" field="bgcolor" type="color"/>
   <input label="Background image" field="bgimage" type="image"/>
   <space />
 </subtab>
   etc.

I have large blocks containing absolutely identical information, e.g. the form fields for defining the background of the page, the content area, the top bar, and so on. This is making the XML file very cumbersome to work with and look through.

Is there a native XML "Copy + Paste" construct / command / statement that tells the XML parser - in my case, simpleXML - to look up the contents of a certain branch from another?

In pseudo-code:

<subtab id="content_background" copyFrom="../page_background">
<!-- sub-elements from "page_background" are magically copied here 
     by the parser -->
</subtab>
A: 

You would create an SimpleXmlElement with the format and use clone, updating any changed attributes or sub tags each time.

Kevin Peno
If I read it right, Pekka wants to copy (clone) elements and append them somewhere else in the tree, and I don't think you can do that with clone. You'd had to use dom_import_simplexml(), cloneNode() then import the result back to SimpleXML.
Josh Davis
Each node in the tree is a simpleXMLElement object. You could take object X (the common node), clone it, and use the append functionality to pump it into the tree (anywhere you like) as another element. I do however like your answer better :)
Kevin Peno
+4  A: 

XML is just a format, so no copy command. XSLT can do that, but it's probably too complicated for your needs.

My advice: create a PHP function that adds your boilerplate elements. For example:

function default_elements(SimpleXMLElement $node)
{
    $default = array(
        'input' => array(
            array('label'=>"Background color", 'field'=>"bgcolor", 'type'=>"color"),
            array('label'=>"Background image", 'field'=>"bgimage", 'type'=>"image")
        ),
        'space' => array(
            array()
        )
    );

    foreach ($default as $name => $elements)
    {
        foreach ($elements as $attrs)
        {
            $new = $node->addChild($name);
            foreach ($attrs as $k => $v)
            {
                $new[$k] = $v;
            }
        }
    }
}
Josh Davis
This looks good. I should be able to integrate this in the parsing process for each element that has a "copyFrom" attribute or so. Thank you!
Pekka