About encodings & entities in PHP5 using DOM XML/XSLT

From: Date: Sun, 03 Oct 2004 17:55:34 +0000
Subject: About encodings & entities in PHP5 using DOM XML/XSLT
Groups: php.xml.dev 
Request: Send a blank email to php-xml-dev+get-474@lists.php.net to get a copy of this message
Handling encodings and entities in XML/XSL Documents is a bit tricky for beginners, I think. Thus I want to present what I found out, hopefully in a simpler manner. First it seems to me that the current DOM Implementation of PHP (5.0.3) and libxml2 respectively do not handle something else then UTF-8 encoding. Even so if you write the encoding as second parameter on construction of the document: $doc = new DOMDocument("1.0", "ISO-8859-1"); Nevertheless, error messages like 'no propper utf-8 encoding in file...' while parsing with $doc->loadXXX() occur. Maybe the behaviour is like >Jirka Kosek wrote: > >> I know that in PHP4 and older xml_parser used expat parser as an >> underlying implementation and was limited to characters in ISO-8859-1. >> According to documentation in PHP5 xml_parser should be built on the top >> of libxml2. Thus I thought that it would support all encodings supported >> by libxml2. My experience is that characters outside of ISO-8859-1 are >> replaced by ? in the same way as expat does it. > >Never mind. I figured out that layering on top of libxml2 is little >non-intuitive, but if I specify optional parameter on >xml_parser_create() I can read document in whatever encoding supported >by libxml2 and this encoding is internally converted into utf-8. > >$parser = xml_parser_create("utf-8"); Anyway, I found out that everything works fine with encodings (i.e. german umlaute etc.)/entities if you consider the following issues: - save your .xml, .xsl files in the right charset: utf-8 encoded. (TextPad for example enables you to choose between ansi, utf8, dos,... this prevends the parser from throwing an exception like mentioned above. - use a dtd to resolve the xhtml entities: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent then you can use &nbsp;, &uuml; etc. easaly. Maybe you get problems with xml editors like xmlspy because of an incomplete dtd.. i've no idea how to avoid this... - set $doc->resolveExternals (to handle external dtd declarations) and $doc->substituteEntities (needed if you want to use entities within transformations) to true. XSL can handle character encodings like &#160; but NOT entity references like &nbsp; (thus substitute them) - use $doc::load() or loadXML() to parse your input xml/xsl file, but $doc::saveHTML() to serialize the DOM to well-formed XHTML code. then the result will be in the right manner, i.e. &#160; will be transformed to &nbsp; again... Finally the whole thing in action: Save this UTF-8 ENCODED!! ****************** XML SOURCE ******************* <!DOCTYPE html PUBLIC "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> or better download the file and do <!DOCTYPE html SYSTEM "DTD/xhtml-lat1.ent"> <html> <body> My&nbsp;Test </body> </html> Save this UTF-8 ENCODED!! ****************** XSL SOURCE ******************* <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" omit-xml-declaration="no"/> <xsl:template match="/"> This is&#160; <!-- character encodings do not need any dtd! --> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet> ****************** PHP SOURCE CODE ******************* <?php $doc = new DOMDocument(); $doc->resolveExternals = true; $doc->substituteEntities = true; $doc->loadXML($xml_source); $xsl = new DOMDOcument(); $xsl->resolveExternals = true; $xsl->substituteEntities = false; $xsl->load("xsl_source.xsl"); $proc = new XSLTProcessor(); $proc->importStylesheet($xsl); print($proc->transformToDoc($doc)->saveHTML()); ?> Maybe this helps someone. If you got some more infos, please let me know. Cya vivi

« previous php.xml.dev (#474) next »