0

Possible Duplicate:
How to insert HTML to PHP DOMNode?
PHP and DOMDocument

I am trying to write a Class that converts an array to XML using DOMDocument - and on top of that imports HTML into the DOM document. Problem is that the HTML is not imported into the DOM document - it gets imported as a text string (for instance, HTML tags are shown as &lt;p&gt; instead of <p> in the source for the resulting XML document).

Update: Code added directly to this Question as requested by Hakre. The code is a bit hacked but works - it would be interesting though to get rid of the extend from DomDocument as suggested by Hakre.

class xmlizer extends DomDocument {

    function __construct() {
        parent::__construct();
    }

    function node_create($arr, $items = null) {
        if (is_null($items))
            $items = $this->appendChild($this->createElement("items"));

        // Loop the array values.
        foreach($arr as $element => $value) {
            // If Array has numeric keys, use "node - else use $element.
            $element = is_numeric( $element ) ? "node" : $element;
            // Create element, add $value unless $value is an array - and append to main object ($items).
            $fragment = $this->createElement($element, (is_array($value) ? null : $value));
            $items->appendChild($fragment);

            // Iterate if $value is an array, .
            if (is_array($value)) {
                self::node_create($value, $fragment);
            }
        }
    }

    public function __toString() {
        // html_entity_decode() added by Micha. Thanks.
        return html_entity_decode($this->saveXML());
    }

}

// Build test Array with HTML string (for testing purposes only).
for($i=0;$i<3;$i++) {
    $j = $i+1;
    $array['example'][] = array(
        "id" => $j,
        "title" => "Title $j",
        "description" => "<p>Text <strong>string</strong> nr. $j with <em>some</em> <code>HTML code</code>.</p>",
        );
}


// Test: Run the code.
header("Content-Type:text/xml");
$xml = new xmlizer();
$xml->node_create($array);
echo $xml;

PS: Please don't close the Question as I don't think this is a duplicate. Thanks.

Community
  • 1
  • 1
Kristoffer Bohmann
  • 3,986
  • 3
  • 28
  • 35
  • @hakre: The suggested solution is using SimpleXML and not DOM - I have chosen not to use SimpleXML because SimpleXML seems to have problems supporting output formatting and CDATA elements. – Kristoffer Bohmann Nov 13 '11 at 14:22
  • 1
    Well [SimpleXML and DOMDocument are interchangeable](http://php.net/manual/en/function.dom-import-simplexml.php) (and the linked answer shows that as well in my first comment). Regarding CDATA you're right, but there is also `LIBXML_NOCDATA` (compare [read cdata from a rss feed](http://stackoverflow.com/questions/8020181/read-cdata-from-a-rss-feed/8020274#8020274)). Not that this solves all your problems, but you can do the same with DOMDocument, see as well Gordon's links. In total all are referring to DOMDocument if you look closely. – hakre Nov 13 '11 at 14:27
  • I tried [Gordon's createDocumentFragment() example](http://stackoverflow.com/questions/4751437/php-dom-append-source-html-to-a-domelement) but was not able to get the objects right (see [code](http://codepad.org/jy31rKAo)). Any help will be appreciated. – Kristoffer Bohmann Nov 13 '11 at 17:51
  • 1
    Can you add the array definition, and the DomDocument based XML conversion to your question so it's more clear what you try to achieve. Looking at your code I assume this can be solved simpler so maybe if you keep things more apart (e.g. I don't see any need to extend from DomDocument, looks complicated). Please specify as well where you want to add the data. Just some example data (but please simplified in case it's a some megabyte large array or XML or so ;) ) - the code you linked does not execute fully. Maybe some description where you want to add what is helpful. – hakre Nov 14 '11 at 11:06
  • @hakre Update: I have added the code directly on this page. I want to add the HTML data to any array value (see the "description" key in my test array). (Note that the array definition is generated on the fly - see my code sample). – Kristoffer Bohmann Nov 14 '11 at 16:19

1 Answers1

0

Try html_entity_decode($value) on line 15 in the second code but why you want the HTML as HTML because then it would be interpreted as XML.

Update Sorry the one above doesn't work and this doesn't work too:

$this
    ->createElement($element)
    ->createTextNode(is_array($value) ? null : $value ));

Finaly I tryed it my self:

I think this is the best solution: http://codepad.org/PpyewkVd

noob
  • 8,982
  • 4
  • 37
  • 65
  • This doesn't load the HTML into the DOM - see http://codepad.org/Y6VoL2Gy. My reason for importing the HTML as XML is to output XML with XSL-templates (with the current import method the HTML encoding remain in the XSL-templates). – Kristoffer Bohmann Nov 13 '11 at 14:15
  • @KristofferBohmann I see but this should work `$this->createElement($element)->createTextNode(is_array($value) ? null : $value ));` – noob Nov 13 '11 at 15:34
  • Not sure exactly where you want to place the createTextNode() - I tried [this code](http://codepad.org/rCcn7W5X) that fails with the error "Call to undefined method DOMElement::createTextNode()". – Kristoffer Bohmann Nov 13 '11 at 19:48