Re: [PHP-XML-DEV] About encodings & entities in PHP5 using DOM XML/XSLT

[email protected] (Christian Stocker) Sun, 03 Oct 2004 20:57:09 +0200
Newsgroups php.xml.dev
Message-ID <[email protected]>

On 3.10.2004 19:55 Uhr, Vivian Steller wrote:
> 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.

The encoding has to be written in the <?xml encoding="foobar" ?> 
processing instruction of the XML document, then it works certainly fine.

Where did you find the
$doc = new DOMDocument("1.0", "ISO-8859-1");

syntax? I don't think, that's a valid one (but maybe i'm wrong, and I'm 
too lazy to read the sources right now). But the encoding of the XML 
Document itself certainly would overwrite that (and if no encoding, then 
it's UTF-8, since that's the default by the specs)

chregu


> 
> 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
> 

-- 
christian stocker | Bitflux GmbH | schoeneggstrasse 5 | ch-8004 zurich
phone +41 1 240 56 70 | mobile +41 76 561 88 60  | fax +41 1 240 56 71
http://www.bitflux.ch  |  [email protected]  |  gnupg-keyid 0x5CE1DECB