Update an XML File With Namespace Prefix

761 views Asked by At

I have an XML file with namespace, and I want to update this file with add more items.

Here my XML file structure:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns="http://feeds.omgeu.com/ns/1.0/" xmlns:omg="http://feeds.omgeu.com/ns/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <channel>
   <item>
      <omg:merchantrank>1</omg:merchantrank>
      <omg:pid>RBK1444C</omg:pid>
   </item>
 </channel>
</rss>

Here my function for adding item:

protected function writeFeedAppend($data,$url)
    {
        set_time_limit(6000); 
        $bucket  = $url;
        $doc = new \DOMDocument('1.0', 'utf-8');
        $doc->formatOutput = true;
        $doc->load($bucket);
        $fragment = $doc->createDocumentFragment();
        $elementChild  = '';
        foreach ($data as $feedData)
        {
            $elementChild .= '<item>';
            $elementChild .= '<omg:merchantrank>';
            $elementChild .= '1';
            $elementChild .= '</omg:merchantrank>';
            $elementChild .= '<omg:pid>';
            $elementChild .= $feedData['number'];
            $elementChild .= '</omg:pid>';
            $elementChild .= '</item>';
            $elementChild .= "\n";
        }
        $fragment->appendXML($elementChild);
        $doc->documentElement->appendChild($fragment);
        $doc->save($bucket);// Save as xml file
    }

With this function I got error: Warning: DOMDocumentFragment::appendXML(): namespace error : Namespace prefix omg on merchantrank is not defined

My question is how to define this namespace, so I can continue add more items to my xml file?

Hope you guys can help me. Thanks

1

There are 1 answers

0
ThW On BEST ANSWER

The top level nodes of the fragment would need to define the prefix. The prefixes are only valid for that element node and its descendants/attributes until redefined on another descendant element node.

...
$elementChild .= '<item xmlns:omg="http://feeds.omgeu.com/ns/1.0/">';   
...

But you should not create the XML as text, use the DOM document methods to create the nodes and append them to the parent.

...
$xmlns_omg = 'http://feeds.omgeu.com/ns/1.0/';
foreach ($data as $feedData) {
  $item = $doc->documentElement->appendChild($doc->createElement('item'));
  $item
    ->appendChild($doc->createElementNS($xmlns_omg, 'omg:merchantrank'))
    ->appendChild($doc->createTextNode('1'));
  $item
    ->appendChild($doc->createElementNS($xmlns_omg, 'omg:pid'))
    ->appendChild($doc->createTextNode($feedData['number']));
}
...

DOMDocument::createElementNS() creates an element node in the given namespace. It adds the namespace definition if needed.

And yes, you can use the same prefix for different namespaces in the same document, or different prefixes for the same namespace.