Jump to content

Problem with include-by-entity


zkarj

Recommended Posts

First a bit of background. I have had a modest amount of PHP running XSL transforms to power one of my web sites for years now and it has all worked fine. Recently I needed to switch hosts and had to go from PHP 4 to PHP 5. This meant changing from sablotron to libxslt. I found a script which enables me to leave all the old calls in and for the most part it works fine. However the new library seems to be a lot more thorough on completely valid XML and DTD.So I have the following album.xml file.<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE album [<!ELEMENT album (picture+)><!ELEMENT picture (type|subtype?|reg?|loc?|date?|event?|op?|comment?)><!ELEMENT type (#PCDATA)><!ELEMENT subtype (#PCDATA)><!ELEMENT reg (#PCDATA)><!ELEMENT loc (#PCDATA)><!ELEMENT date (#PCDATA)><!ELEMENT event (#PCDATA)><!ELEMENT op (#PCDATA)><!ELEMENT comment (#PCDATA)><!ATTLIST picture id ID #REQUIRED> <!ATTLIST picture large CDATA #IMPLIED> <!ATTLIST op id CDATA #IMPLIED> <!ENTITY album00 SYSTEM "album00.xml"><!ENTITY album01 SYSTEM "album01.xml"><!ENTITY album02 SYSTEM "album02.xml"><!ENTITY album03 SYSTEM "album03.xml"><!ENTITY album04 SYSTEM "album04.xml"><!ENTITY album05 SYSTEM "album05.xml"><!ENTITY album06 SYSTEM "album06.xml"><!ENTITY album07 SYSTEM "album07.xml"><!ENTITY album08 SYSTEM "album08.xml"><!ENTITY album09 SYSTEM "album09.xml">]><album>&album00;&album01;&album02;&album03;&album04;&album05;&album06;&album07;&album08;&album09;</album>The DTD declaration, in terms of elements and attributes was originally external and referred to a fictitious DTD and Sablotron didn't seem to care. The main reason for the DTD declaration was the ENTITYs. This is my method for including all the albumXX.xml files, in turn a method of splitting up a large XML file for easier editing.So my problem is this. After inserting the compatibility script and fixing up declarations and the like, my site is essentially working except for one thing. It is all about cataloging and displaying photos and it does everything except show the photos!Each of the albumXX.xml files contains lots of entries like this: <picture id="av0819"> <type>at6</type> <reg>ZK-TVI</reg> <op>nzwb</op> <loc>NZAR</loc> <date>20031004</date> </picture>The idea is I can list photos by type, reg, op, loc etc. When I bring up one such page, I get NO matches to any picture elements. This is true for all catalog types and all parameter values. I have proven that the parameter value is passed successfully and I can prove that the parser is seeing all the picture elements because I copied the above <picture> element directly into album.xml and got a parser error saying id av0819 was declared twice. Furthermore, if I then remove the &album08; entity (thus removing the duplication) then that single photo matches (assuming I specify the right parameter value) and everything (with respect to that photo) works.Further to this, in my category listings I have a count of the number of matching photos and THAT WORKS! I see the correct counts shown.I have proven that the issue is no matching picture elements (by putting debugging output both immediately prior to the relevant <xsl:apply-templates> and within the <xsl:template> for "picture" elements.) What I don't understand is why there are no matches for the included photos (in the case of displaying the elements) when there are clearly elements which would match, and yet the counting of the SAME elements works fine.Here is the catalog page for types:<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" indent="no" encoding="UTF-8" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd"/><xsl:variable name="pfile" select="document('album.xml')/album"/><xsl:template match="types"> <html> <head> <title>ZK-ARJ: Aviation Type Galleries</title> <link rel="stylesheet" type="text/css" href="../zkarj2.css"/> </head> <body> <div class="center"><p><img class="std" src="../resource/zklogol.gif" width="153" height="48"/></p><h1 class="std">Aviation Type Galleries</h1></div> <div class="nav"> <xsl:copy-of select="document('../resource/nav.xml')/nav[@type=sub1]/*"/> </div> <div class="head">Generic types</div> <p>Generic types cover all those aircraft not allocated a Specific Type gallery. (See below.)</p> <table class="contents"><tr> <xsl:variable name="size1" select="count(type[@class=generic])"/> <xsl:variable name="split1" select="ceiling($size1 div 3)"/> <xsl:for-each select="type[@class=generic][position() mod $split1 = 1]"> <td><xsl:apply-templates select=".|following-sibling::type[@class=generic][position() < $split1]"/></td> </xsl:for-each> </tr></table><div class="center"><table class="ad"><tr><td><script type="text/javascript"><xsl:text><!--google_ad_client = "pub-3134991060092913";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_channel ="1039463094";google_ad_type = "text";google_color_border = "000000";google_color_bg = "F0F0F0";google_color_link = "0000FF";google_color_url = "008000";google_color_text = "000000";//--></xsl:text></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><br/><span class="tiny">These advertisements are provided by Google and therefore we can make no assertions in respect to the contents or services being offered</span></td></tr></table></div> <div class="head">Specific types</div> <p>The Specific Type galleries are generally allocated for aircraft types of which I have at least three photos and in more than one location.</p> <table class="contents"><tr> <xsl:variable name="size2" select="count(type[@class=specific])"/> <xsl:variable name="split2" select="ceiling($size2 div 3)"/> <xsl:for-each select="type[@class=specific][position() mod $split2 = 1]"> <td><xsl:apply-templates select=".|following-sibling::type[@class=specific][position() < $split2]"/></td> </xsl:for-each> </tr></table> <div class="nav"> <xsl:copy-of select="document('../resource/nav.xml')/nav[@type=sub1]/*"/> <xsl:copy-of select="document('../resource/copy.xml')/copyright"/> </div> </body> </html></xsl:template><xsl:template match="type"> <xsl:variable name="this" select="@code"/> <p><a href="typegal.php?type={@code}"><xsl:value-of select="./fullname"/></a> (<xsl:value-of select="count($pfile/picture[type=$this])"/>)</p></xsl:template></xsl:stylesheet>And the catalog page itself...<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" indent="yes" encoding="UTF-8" doctype-public="-//W3C//DTD HTML 4.01//EN" doctype-system="http://www.w3.org/TR/html4/strict.dtd"/><xsl:param name="type">dh82</xsl:param><xsl:variable name="typedef" select="document('types.xml')/types/type[@code=$type]"/><xsl:variable name="afile" select="document('amazon.xml')/amazon"/><xsl:template match="album"> <html> <head> <title>ZK-ARJ: <xsl:value-of select="$typedef/fullname"/></title> <link rel="stylesheet" type="text/css" href="../zkarj2.css"/> </head> <body> <div class="center"><p><img class="std" src="../resource/zklogol.gif" width="153" height="48" alt="ZK-ARJ"/></p><h1 class="std"><xsl:value-of select="$typedef/fullname"/></h1></div> <div class="nav" xml:space="preserve"> <xsl:copy-of select="document('../resource/nav.xml')/nav[@type=sub1]/*" xml:space="preserve"/> </div><div class="center"><table class="ad"><tr><td><script type="text/javascript"><xsl:text><!--google_ad_client = "pub-3134991060092913";google_ad_width = 468;google_ad_height = 60;google_ad_format = "468x60_as";google_ad_channel ="1039463094";google_ad_type = "text";google_color_border = "000000";google_color_bg = "F0F0F0";google_color_link = "0000FF";google_color_url = "008000";google_color_text = "000000";//--></xsl:text></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><br/><span class="tiny">These advertisements are provided by Google and therefore we can make no assertions in respect to the contents or services being offered</span></td></tr></table></div> <div class="head">Type description</div> <xsl:apply-templates select="$typedef/description"/> <div class="head">Gallery</div> <div class="null"><xsl:apply-templates select="picture[type=$type]"/></div> <xsl:if test="$afile/set[assoc/@level=type][assoc=$type]"><table class="amazon"><tr><td><img src="../resource/126X32-w-logo.gif" width="126" height="32"/></td> <td><xsl:apply-templates select="$afile/set[assoc/@level=type][assoc=$type]"></xsl:apply-templates></td></tr></table></xsl:if> <div class="nav" xml:space="preserve"> <xsl:copy-of select="document('../resource/nav.xml')/nav[@type=sub1]/*"/> <xsl:copy-of select="document('../resource/copy.xml')/copyright/*"/> </div> </body> </html></xsl:template><xsl:template match="picture"> <xsl:variable name="dir" select="substring(@id,1,4)"/> <a href="photo.php?id={@id}" target="_blank"> <xsl:choose> <xsl:when test="comment"> <img class="thumb" src="gallery/{$dir}/t{@id}.jpg" alt="{@id}{normalize-space(comment)}" /> </xsl:when> <xsl:otherwise> <img class="thumb" src="gallery/{$dir}/t{@id}.jpg" alt="{@id}" /> </xsl:otherwise> </xsl:choose> </a></xsl:template><xsl:template match="description"> <xsl:apply-templates/></xsl:template><xsl:template match="p"> <xsl:copy-of select="."/></xsl:template><xsl:template match="set"> <p>View <a href="amaztype.php?type={$typedef/@code}&media={@media}">selected <xsl:value-of select="@media"/></a> about the <xsl:choose> <xsl:when test="subject"><xsl:value-of select="subject"/></xsl:when> <xsl:otherwise> <xsl:value-of select="$typedef/fullname"/></xsl:otherwise></xsl:choose> from Amazon.com</p></xsl:template></xsl:stylesheet>You can see these in operation here: http://www.zkarj.co.nz/aviation/types.phpI would appreciate any suggestions on what to look at here!

Link to comment
Share on other sites

In the script you're using, right under the line

$xml=new DOMDocument();

add

$xml->validateOnParse = false;

and it should all be fine.If it still doesn't work, also add:

$xml->resolveExternals = true;$xml->substituteEntities = true;

Add the same for the $xsl variable if you need to (though in your case, you don't need to).If you could, I'd really advise you to completely migrate to the libxml and libxslt APIs though. They are really great in that they allow you to create error recovery points all the way. For example, you can do:

if (!$xml->load('album.xml')) {	$error = libxml_get_last_error();	die('The XML is not well formed. The error occured on line ' . $error->line . ' and the message was "' . $error->message . '". Correct the error and try again.');}

Link to comment
Share on other sites

In the script you're using, right under the line
$xml=new DOMDocument();

add

$xml->validateOnParse = false;

and it should all be fine.If it still doesn't work, also add:

$xml->resolveExternals = true;$xml->substituteEntities = true;

Thanks! That did the trick. Had to add all three lines.I did start making the conversion on one file but began to hit all the declaration problems, then when I inserted the script and it mostly worked, I went down that track.I'll have another crack at converting soon. In the meantime, it's operational again. Yay! Thanks again.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...