0

I have two xml arrays, and i want to merge these arrays in a third array... the first xml struxture is

$current = '<forms id="frm16648">
  <group ref="" id="tarascioheader" mode="block">
    <label>
    <![CDATA[Group (tarascioheader)]]>
    </label> structure u
    <select ref="" id="petorresp">
      <label>
      <![CDATA[Select (petorresp)]]>
      </label>
    </select>

and the 2nd array is

$old = '<forms id="frm16648">
  <group ref="" id="tarascioheader" mode="block">
    <label>
    <![CDATA[abc]]>
    </label>
 </group>
</forms>':
  </group>
</forms>';

from these xmls, i want to copy all the matching tags in the new array.... I am trying to do this by a recursive function which is....

function merge_xmls($current, $old) 
{

    $cxml = str_get_html($current); 
    $oxml = str_get_html($old); 
    do
    {
        $tt = $cxml->first_child();
        if(!empty($tt) && !is_null($cxml->first_child()))
        {

            $x = $cxml->first_child();

            $this->merge_xmls($x, $cxml, $oxml);
        }
        if(empty($tt))
        {
            $cid = $cxml->id;
            $oid = $oxml -> find('#'.$cid);
            if(!is_null($oid))
            {
                $cxml -> innerHTML = $oxml -> innerHTML;
            }
        }
        $cxml = $cxml->next_sibling();
    }
    while(!empty($cxml) && !is_null($cxml));
}
Bilal
  • 51
  • 1
  • 8
  • What is your expected output? – HILARUDEEN S ALLAUDEEN Nov 02 '13 at 18:19
  • There are no such things as *XML Arrays* in PHP. What are you talking about? Also there is no `$this` - Please create a self-contained *working* example that demonstrates your issue with as little data and code as necessary. – hakre Nov 02 '13 at 18:19
  • Are you trying to use SimpleXML? Like hakre said, there are no such things as XML arrays but you could build an array out of one. Is that what you're trying to do? – Machavity Nov 02 '13 at 18:22
  • Also your code is pretty wired. Please remove any superfluous code there. It's okay to assign the variable once, there is no need to call the same method all over again and assign it to another variable. Also give the variables proper names. – hakre Nov 02 '13 at 18:22

1 Answers1

0

From the pseudo code you've posted it looks like you want to copy over the children of one xml element to another. As I use a different parser, I to it a little differently, but the same:

  1. Find all elements to copy into.
    1. Find the element to copy from based on the one found to copy into.
    2. Remove all children of the element to copy into.
    3. Copy all children from into

I do it here with DOMDocument as it's a good fit for dedicated operations like such:

$doc = new DOMDocument();

$copyTo = $doc->createDocumentFragment();
$copyTo->appendXML($current);

$copyFrom = new DOMDocument();
$copyFrom->loadXML($old);

$xpath = new DOMXPath($copyFrom);

foreach (new DOMElementFilter($copyTo->childNodes, 'forms') as $form) {
    $id         = $form->getAttribute('id');
    $expression = sprintf('(//*[@id=%s])[1]', xpath_string($id));
    $copy       = $xpath->query($expression)->item(0);

    if (!$copy) {
        throw new UnexpectedValueException("No element with ID to copy from \"$id\"");
    }

    dom_replace_children($copy, $form);
}

Output is as:

echo $doc->saveXML($doc->importNode($copyTo, TRUE));

and gives:

<forms id="frm16648">
  <group ref="" id="tarascioheader" mode="block">
    <label>
    <![CDATA[abc]]>
    </label>
 </group>
</forms>

The helping routines here are:

function dom_remove_children(DOMElement $node)
{
    while ($node->firstChild) {
        $node->removeChild($node->firstChild);
    }
}

function dom_replace_children(DOMElement $from, DOMElement $into)
{
    dom_remove_children($into);

    $doc = $into->ownerDocument;

    foreach ($from->childNodes as $child) {
        $into->appendChild($doc->importNode($child, TRUE));
    }
}

Also DOMElementFilter class (via PHP DOM: How to get child elements by tag name in an elegant manner?) and there's the xpath_string() function (also as shown on Stackoverflow).

Hope this helps, the example works with your data for me this way: https://eval.in/59886

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836