Christoph: foreach-Schleife liest nichts aus

Hallo,

ich will mittels einer XSL-Datei mein XML-Dokument auslesen. Aber das funktioniert nicht so richtig. In der XML-Datei stehen ja eine Menge von Attributen drin, die ich aber alle gar nicht benötige, ich brauch eigentlich nur 3 (title,summery,channel). Auslesen tut er mir davon aber keins. Die XML-Struktur darf ich auch nicht verändern, da die von SOLR so vorgegeben wurde...

Meine DTD sieht so aus:

<!ELEMENT response (doc)*>
<!ELEMENT doc  (title,summery,channel)>
<!ELEMENT title  (#PCDATA)>
<!ELEMENT summery (#PCDATA)>
<!ELEMENT channel (#PCDATA)>

Meine XSL-Datei so:

  
<?xml version="1.0" encoding="iso-8859-1"?>  
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
 <xsl:template match="/">  
  <html>  
  <head>  
  </head>  
  <body>  
   <table border="1">  
   <tr>  
    <td><b>Titel</b></td>  
    <td><b>Text</b></td>  
   </tr>  
   <xsl:for-each select="response/doc">  
   <tr>  
    <td valign="top"><xsl:value-of select="title" /></td>  
    <td valign="top"><xsl:value-of select="summery" /></td>  
   </tr>  
   </xsl:for-each>  
   </table>  
  </body>  
  </html>  
 </xsl:template>  
</xsl:stylesheet>  

Und meine XML-Datei gekürzt so:

  
<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE response SYSTEM "response.dtd">  
<?xml-stylesheet type="text/xsl" href="response.xsl" ?>  
<response>  
 <lst name="responseHeader">  
  <int name="status">0</int>  
  <int name="QTime">2</int>  
 </lst>  
 <result name="response" numfound="18" start="0" maxscore="0.4055336">  
  <doc>  
   <float name="score">0.4055336</float>  
   <str name="body">Text, ganz viel Text über seidene Haare...</str>  
   <arr name="channel"><str>beauty-wellness/schoene-haare_tipps-tricks</str></arr>  
   <arr name="domain"><int>1</int><int>2</int><int>3</int></arr>  
   <str name="name">glaenzende_Haare</str>  
   <int name="nid">13</int>  
   <str name="summery">"Pailletten, Seide, Lurex: Nicht nur auf den Laufstegen funkelt und glitzert es. Auch das Haar erstrahlt in neuem Glanz. Pflege- und Stylingtipps vom wellaflex-Styling-Experten wellaflex-Styling-Experte Sascha Breuer verrät die Tricks, wie Sie mehr Glanz in Ihre Haare zaubern."</str>  
   <str name="title">"Glänzende  Aussichten"</str>  
  </doc>  
  <doc>  
   <float name="score">0.35223204</float>  
   <str name="body">Ganz viel Text über schöne Haare</str>  
   <arr name="channel"><str>beauty-wellness/schoene-haare_tipps-tricks</str></arr>  
   <arr name="domain"><int>1</int><int>2</int><int>3</int></arr>  
   <str name="name">Zeitlos_schoenes_Haar</str>  
   <int name="nid">5</int>  
   <str name="summery">"Können Sie sich noch an Ereignisse erinnern, die uns in den vergangenen zwei Jahren beschäftigten? Wir wurden Papst, ganz Deutschland war im Fußballfieber und Desperate Housewives löste Sex &amp; the City ab. Und was ist noch passiert? Gar nicht so leicht, sich zu erinnern, oder?"</str>  
   <str name="title">"Zeitlos schönes Haar"</str>  
  </doc>  
 </result>  
</response>  

  1. Hallo,

    du musst in der for-each-Schleife ja auch den ganzen Pfad angeben und darfst keine Elemente wie in deinem Fall "result" auslassen. Also besser response/result/doc.

    Auf Attribute greift man zu, wenn man ihnen ein @ voran stellt. Hier musst du testen, was in deinem Attribut drin steht: @name=title. Verwende hierfür xsl:if oder xsl:choose.

    Deine DTD passt auch irgendwie überhaupt nicht zu dem XML.

    Gruß,
    Leeloo

    --
    "Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra
    1. Hi

      du musst in der for-each-Schleife ja auch den ganzen Pfad angeben und darfst keine Elemente wie in deinem Fall "result" auslassen. Also besser response/result/doc.

      Gut, danke, das hat schon mal geklappt.

      Auf Attribute greift man zu, wenn man ihnen ein @ voran stellt. Hier musst du testen, was in deinem Attribut drin steht: @name=title. Verwende hierfür xsl:if oder xsl:choose.

      Das versteh ich dann doch wiederum weniger. Ich hatte halt probiert:
      <xsl:if str="@name='title'"> Aber dann bekam ich einen XML-Fehler zurück.

      Deine DTD passt auch irgendwie überhaupt nicht zu dem XML.

      Warum nicht? Bin leider blutiger Anfänger :/

      Grüße

      Christoph

      1. Hallo,

        Das versteh ich dann doch wiederum weniger. Ich hatte halt probiert:
        <xsl:if str="@name='title'"> Aber dann bekam ich einen XML-Fehler zurück.

        So gehts net ganz. Statt 'str', musst du 'test' schreiben. Um jedoch auf das Attribut zuzugreifen, musst du dich halt in dem Element befinden. In dem Fall str. Aber die Lösung von ThomasM sollte auch funktionieren.

        Deine DTD passt auch irgendwie überhaupt nicht zu dem XML.

        Warum nicht? Bin leider blutiger Anfänger :/

        Du definierst Attribut-Werte als Elemente. Schau dich doch mal hier ein wenig um. Du hast die Elemente response, lst, int, result, doc, float, str, arr und als einziges Attribut halt name in einigen dieser Elemente. Schau dir die Beispiele auf der Seite an, dann solltest du die richtige DTD hinkriegen.

        Gruß,
        Leeloo

        --
        "Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra
  2. Hallo Christoph,

    <xsl:for-each select="response/doc">
       <tr>
        <td valign="top"><xsl:value-of select="title" /></td>
        <td valign="top"><xsl:value-of select="summery" /></td>
       </tr>
       </xsl:for-each>

    Gesucht ist der XML-Struktur nach eher:

    <xsl:value-of select="str[@name='title']/text()" />  
    <xsl:value-of select="str[@name='summary']/text()" />
    

    Grüße,
    Thomas

    1. Hi Thomas

      Gesucht ist der XML-Struktur nach eher:

      <xsl:value-of select="str[@name='title']/text()" />

      <xsl:value-of select="str[@name='summary']/text()" />

        
      Ja oder so ;) Und wenn ich jetzt mir noch die URL für den Titel zusammen bastel würde, wie könnte ich die denn in ein a href reinkriegen?  
        
      Mit <xsl:value-of select="arr[@name='channel']" />/<xsl:value-of select="str[@name='name']" />.html bekomm ich ja den vollständigen Link raus, aber wie kann ich das Ganze jetzt noch verlinken?  
        
      Grüße Christoph
      
      1. Hallo,

        Hi Thomas

        Gesucht ist der XML-Struktur nach eher:

        <xsl:value-of select="str[@name='title']/text()" />

        <xsl:value-of select="str[@name='summary']/text()" />

        
        >   
        > Ja oder so ;) Und wenn ich jetzt mir noch die URL für den Titel zusammen bastel würde, wie könnte ich die denn in ein a href reinkriegen?  
        >   
        > Mit <xsl:value-of select="arr[@name='channel']" />/<xsl:value-of select="str[@name='name']" />.html bekomm ich ja den vollständigen Link raus, aber wie kann ich das Ganze jetzt noch verlinken?  
          
        Nennt sich [xsl:attribute](http://de.selfhtml.org/xml/darstellung/xsltelemente.htm#attribute) - wenn du das suchst.  
          
        Gruß,  
        Leeloo
        
        -- 
        "Als es noch keine Computer gab, war das Programmieren noch relativ einfach." - Edsger W. Dijkstra
        
        1. Hi

          Nennt sich xsl:attribute - wenn du das suchst.

          Danke, jetzt geht es :D Jetzt muss ich nur noch die DTD ordentlich hinbiegen :)

      2. Hallo Christoph,

        Mit <xsl:value-of select="arr[@name='channel']" />/<xsl:value-of select="str[@name='name']" />.html bekomm ich ja den vollständigen Link raus, aber wie kann ich das Ganze jetzt noch verlinken?

        Mittels Attribute Value Templates -> {XPath-Ausdruck}:

        <a href="{arr[@name='channel']}/{str[@name='name']}.html">Linktext, ggf. als xsl:value-of ... abgreifen</a>

        BTW: xsl:attribute wird erst benötigt, wenn der Attributname dynamisch belegt werden soll oder der Attributinhalt noch zusammengesetzt werden muss (z. B. wenn man die Koordinaten eines SVG-Polygons im points-Attribut aus XML-Daten als Liste in der Form "x1,y1 x2,y2 ... xn,yn" aufbaut).

        Grüße,
        Thomas