About encodings & entities in PHP5 using DOM XML/XSLT
[email protected] (Vivian Steller) Sun, 03 Oct 2004 19:55:34 +0200
| Newsgroups | php.xml.dev |
|---|---|
| Organization | eecoo |
| Message-ID | <[email protected]> |
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 , ü 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  
but NOT entity references like (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.   will be transformed to
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 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  <!-- 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