andres: PHP transformToXml funktioniert nicht mehr. Debugging-Tips

Liebe alle,

ich benutze XSLT um die Gigs auf unserer Homepage nach Datum zu sortieren und nur Gigs nach <refdate> anzuzeigen. Eine Sortier- und Filter-Funktion.

Seit ein paar Tagen funktioniert das Skript nicht mehr bzw. liefert es mir einen leeren XML-String ($gigxmloutput). Ich verwende XSL nicht regelmäßig und es ist für mich nicht ersichtlich wo der Fehler liegt, zumal das Script die letzten zwei Jahre problemlos funktioniert hat.

Ich habe das Ganze auf http://www.xsltcake.com/ getestet. Auch hier erhalte ich als Ergebnis einen leeren XML-String : <gigs></gigs>. Ohne irgendwelche Fehlermeldungen. Deshalb tu ich mich schwer, bzw. ist es für mich nahezu unmöglich das Script zu debuggen.

Deshalb meine Frage an euch, ob jemand den Fehler erkennt, oder mir Tipps zum Debuggen von XSL geben kann?

XML-Sample (von php generiert. Variable $gigxml):
refdate dient dazu nur Gigs ab einem bestimmten Datum anzuzeigen.

  
<?xml version="1.0" encoding="UTF-8"?>  
<gigs>  
    <refdate>20141207</refdate>  
    <gig>					<id>3668</id>  
    <where>D- Stuttgart</where>  
    <title>20-Jahre MOUNTAINBIKE-Magazin.de</title>  
    <date>20.11.2014</date>  
    <time>20:30</time>  
    <hp>www.mountainbike-magazin.de</hp>  
</gig>  
<gig>  
    <id>3664</id>  
    <where>Bozen (Batzen Häusl)</where>  
    <title>Bierfest</title>  
    <date>26.09.2014</date>  
    <time>19:00</time>  
    <hp></hp>  
</gig>  
</gigs>

XSL (von php generiert. Variable: $gigxsl):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
    <xsl:template match="/">  
        <gigs>  
            <xsl:for-each select="gigs/gig/date">  
                <!-- Sort Gigs by Date -->  
                <xsl:sort data-type="number" select="substring(.,7,4)">  
                    <xsl:sort data-type="number" select="substring(.,4,2)">  
                        <xsl:sort data-type="number" select="substring(.,1,2)">  
                            <!-- Display only feature gigs -->  
                            <xsl:variable name="isodate" select="concat(substring(.,7,4),substring(.,4,2),substring(.,1,2))">  
                                <xsl:if test="$isodate >  
                                    ancestor::gigs/refdate">  
                                    <gig>  
                                        <title>  
                                            <xsl:value-of select="parent::gig/title"></xsl:value-of>  
                                        </title>  
                                        <id>  
                                            <xsl:value-of select="parent::gig/id"></xsl:value-of>  
                                        </id>  
                                        <imgurl>  
                                            <xsl:value-of select="parent::gig/imgurl"></xsl:value-of>  
                                        </imgurl>  
                                        <date>  
                                            <xsl:value-of select="."></xsl:value-of>  
                                        </date>  
                                        <time>  
                                            <xsl:value-of select="parent::gig/time"></xsl:value-of>  
                                        </time>  
                                        <where>  
                                            <xsl:value-of select="parent::gig/where"></xsl:value-of>  
                                        </where>  
                                        <privat>  
                                            <xsl:value-of select="parent::gig/privat"></xsl:value-of>  
                                        </privat>  
                                        <hp>  
                                            <xsl:value-of select="parent::gig/hp"></xsl:value-of>  
                                        </hp>  
                                    </gig>  
                                </xsl:if>  
                            </xsl:variable>  
                        </xsl:sort>  
                    </xsl:sort>  
                </xsl:sort>  
            </xsl:for-each>  
        </gigs>  
    </xsl:template>  
</xsl:stylesheet>

PHP-Transformation:

$gigxmloutput = transform($gigxml, $gigxsl);  
  
function transform($xml, $xsl) {  
   $xslt = new XSLTProcessor();  
   $xslt->importStylesheet(new  SimpleXMLElement($xsl));  
   return $xslt->transformToXml(new SimpleXMLElement($xml));  
}

Vielen Dank im Voraus,

Andres

  1. Hallo Andreas,

    Ich habe das Ganze auf http://www.xsltcake.com/ getestet. Auch hier erhalte ich als Ergebnis einen leeren XML-String : <gigs></gigs>. Ohne irgendwelche Fehlermeldungen. Deshalb tu ich mich schwer, bzw. ist es für mich nahezu unmöglich das Script zu debuggen.

    Deshalb meine Frage an euch, ob jemand den Fehler erkennt, oder mir Tipps zum Debuggen von XSL geben kann?

    Vermutlich soll es so ablaufen:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
      <xsl:template match="/">  
        <gigs>  
          <xsl:for-each select="gigs/gig/date">  
            <!-- Sort Gigs by Date -->  
            <xsl:sort data-type="number" select="substring(.,7,4)"/>  
            <xsl:sort data-type="number" select="substring(.,4,2)"/>  
            <xsl:sort data-type="number" select="substring(.,1,2)"/>  
            <!-- Display only feature gigs -->  
            <xsl:variable name="isodate"  
                          select="concat(substring(.,7,4),substring(.,4,2),substring(.,1,2))"/>  
            <xsl:if test="$isodate > ancestor::gigs/refdate">  
              <gig>  
                <title>  
                  <xsl:value-of select="parent::gig/title"/>  
                </title>  
                <id>  
                  <xsl:value-of select="parent::gig/id"/>  
                </id>  
                <imgurl>  
                  <xsl:value-of select="parent::gig/imgurl"/>  
                </imgurl>  
                <date>  
                  <xsl:value-of select="."/>  
                </date>  
                <time>  
                  <xsl:value-of select="parent::gig/time"/>  
                </time>  
                <where>  
                  <xsl:value-of select="parent::gig/where"/>  
                </where>  
                <privat>  
                  <xsl:value-of select="parent::gig/privat"/>  
                </privat>  
                <hp>  
                  <xsl:value-of select="parent::gig/hp"/>  
                </hp>  
              </gig>  
            </xsl:if>  
          </xsl:for-each>  
        </gigs>  
      </xsl:template>  
    </xsl:stylesheet>
    

    Wesentliche Probleme waren:

    • Variable falsch befüllt
    • xsl:sort kann nicht mit xsl:sort verschachtelt werden

    Allerdings kommt noch kein Output zustande, weil die gig-Datumswerte kleiner als der Referenzwert sind. Dieser kleiner-Vergleich wäre zielführender:

    <xsl:if test="$isodate &gt; ancestor::gigs/refdate">
      <!-- … -->
    </xsl:if>

    Hinweis: Durch mehrere xsl:template-Konstrukte plus xsl:apply-templates ließe sich der Code besser strukturieren, die Nutzung der Achsenbezeichner könnte auch vermieden werden.

    Grüße,
    Thomas

    1. Vielen Dank dafür, das hat mir enorm weitergeholfen.

      andres

  2. Nachtrag der aufgeräumten Struktur (hier mit der kleiner-Abfrage):

    <?xml version="1.0" encoding="UTF-8"?>  
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
      
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>  
      
      <xsl:variable name="refdate" select="/gigs/refdate"/>  
      
      <xsl:template match="gigs">  
        <gigs>  
          <xsl:apply-templates select="gig">  
            <xsl:sort data-type="number" select="substring(date,7,4)"/>  
            <xsl:sort data-type="number" select="substring(date,4,2)"/>  
            <xsl:sort data-type="number" select="substring(date,1,2)"/>  
          </xsl:apply-templates>  
        </gigs>  
      </xsl:template>  
      
      <xsl:template match="gig">  
        <xsl:variable name="isodate"  
                      select="concat(substring(date,7,4),substring(date,4,2),substring(date,1,2))"/>  
        <xsl:if test="$isodate &lt; $refdate">  
          <gig>  
            <title><xsl:value-of select="title"/></title>  
            <id><xsl:value-of select="id"/></id>  
            <imgurl><xsl:value-of select="imgurl"/></imgurl>  
            <date><xsl:value-of select="date"/></date>  
            <time><xsl:value-of select="time"/></time>  
            <where><xsl:value-of select="where"/></where>  
            <privat><xsl:value-of select="privat"/></privat>  
            <hp><xsl:value-of select="hp"/></hp>  
          </gig>  
        </xsl:if>  
      </xsl:template>  
      
    </xsl:stylesheet>
    

    Grüße,
    Thomas