Avatar billede tjacob Juniormester
30. oktober 2003 - 13:18 Der er 5 kommentarer og
1 løsning

Loop <xsl:for-each> problem

Jeg er nybegynder i XML og XSL (er dog bekendt med HTML og 'normal' programmering), og
har efter et par dages forsøg (og søgning på nettet) givet [midlertidigt] op:

Hvordan looper jeg igennem andet end nodes?

EksempelXML:

<rod>
  <x>163523598664724205</x>  'alle <x> er altid lige lange (her: 18)
  <x>435036575320687842</x>
  <x>764530407894798624</x>
  osv
</rod>

jeg looper igennem hvert element:
<xsl:for-each select="rod/x">
  'her gøres noget; f.eks. opret en række i tabel (<tr>)
  osv

Jeg ønsker ydermere at loope igennem hver enkelt karakter i hvert elements streng:

f.eks. i ovenstående:  <xsl:value-of select="."/>

    = "163523598664724235" er første elements værdi (streng)
    'her skal der loopes igen:
    1    'her gøres noget; f.eks. teste karakter og/eller opret celle i tabel (<td>)
    6            ----
    3            ----
    5            ----
    2            ----
    osv
   
    Hvordan?

    Det må være noget med string-length() og substring(string,i,1) (hvordan findes i?)
    men jeg kender simpelthen ikke nok til sproget -endnu, til at
    kunne konstruere syntaxen.

    Jeg ønsker [med ovenstående eksempelXML] at kunne (for eksempel):
    -oprette en tabel med 3 rækker og 18 kolonner (3 og 18 er IKKE kendt).
    hver celle har en forskellig baggrundsfarve alt efter værdi: 0-9

Jeg har en tåget forestilling om, at dette kan gøres (måske nemmere?) med
noget DOM (eller Java - VBScript m.m.)
-men det er et principielt spørgsmål for mig, så hvordan gøres (kan?) det i XSL?

/tjacob
Avatar billede atoft Nybegynder
30. oktober 2003 - 13:56 #1
Hej,

Du bliver nødt til at køre rekursivt for at kunne løse dit problem. Noget alla nedenstående.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <table>
            <xsl:apply-templates select="//x"/>
        </table>
    </xsl:template>
    <xsl:template mode="x">
        <tr>
            <xsl:call-template name="loop">
                <xsl:with-param name="v" select="."/>
            </xsl:call-template>
        </tr>
    </xsl:template>
    <xsl:template name="loop">
        <xsl:param name="v"/>
        <td>
            <xsl:value-of select="substring(v$,1,1)"/>
        </td>
        <xsl:if test="string-length($v) &gt; 1">
            <xsl:call-template name="loop">
                <xsl:with-param name="v" select="substring($v,2)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
Avatar billede atoft Nybegynder
30. oktober 2003 - 13:57 #2
Det var selvfølgelige et forsøg på et svar :-)
Avatar billede tjacob Juniormester
30. oktober 2003 - 14:52 #3
atoft:

Jeg kender godt begrebet rekursivt, men da jeg -som nævnt- er nybegynder
i dette sprog, er din kode -næsten- sort snak for mig.

Det jeg kan forholde mig til:

Hvis jeg refererer til din kode (gemt som Eksp.xsl) i en eks: XML-fil:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="Eksp.xsl"?>
<rod>
    <x>1234231461245234</x>
    <x>2233234522353445</x>
    <x>1144351234144512</x>
    <x>4321234231242344</x>
</rod>

Så svarer min XML parser (Win XP, IE6):

XML-siden kan ikke vises
XML-kan ikke vises ved hjælp af typografiarket XSL.m.m.

xsl:template må ikke have en tilstandsattribut, hvis den ikke har en tilsvarende attribut.

/tjacob
Avatar billede atoft Nybegynder
30. oktober 2003 - 14:57 #4
det er fordi

<xsl:template mode="x"> skal ændres til

<xsl:template match="x">

sorry
Avatar billede atoft Nybegynder
30. oktober 2003 - 15:03 #5
Det jeg kort fortalt gør er.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <table>
            <!-- find alle x 'elementer og send dem til x templaten -->
            <xsl:apply-templates select="//x"/>
        </table>
    </xsl:template>
    <!-- behandel x elementerne - en ad gangen -->
    <xsl:template match="x">
        <tr>
            <!-- kald loop templaten -->
            <xsl:call-template name="loop">
                <!-- sæt parameter v = x -->
                <xsl:with-param name="v" select="."/>
            </xsl:call-template>
        </tr>
    </xsl:template>
    <xsl:template name="loop">
        <xsl:param name="v"/>
        <td>
            <!-- print værdien -->
            <xsl:value-of select="substring(v$,1,1)"/>
        </td>
        <!-- hvis længden af v er over 1 kald loop igen -->
        <xsl:if test="string-length($v) &gt; 1">
            <xsl:call-template name="loop">
                <!-- men fjern lige den værdi fra strengen vi lige har printet -->
                <xsl:with-param name="v" select="substring($v,2)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Håber eksemplet er blevet mere forståeligt nu
Avatar billede tjacob Juniormester
30. oktober 2003 - 15:08 #6
Det er det!  Mange Tak  -Det virker nu.

/tjacob
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester