Avatar billede marrix Juniormester
13. oktober 2005 - 09:09 Der er 27 kommentarer og
2 løsninger

Gennemløb af (x)html

Hej eksperter ... igen

Det burde være så simpelt, men jeg kan ikke få det til at virke. Lidt forenklet har jeg følgende problem:

En xhtml-fil:
<html>
<head><title>Min side</title></head>
<body>
<p>Noget tekst</p>
<p>Noget mere tekst</p>
<ol>
<li>. liste</li>
<li>. liste</li>
</ol>
<table>
<tr><td>Kr.</td><td>Øre</td></tr>
<tr><td id='kr'>500</td><td id='oere'>50</td></tr>
<tr><td id='kr'>150</td><td id='oere'>75</td></tr>
</table>
</body>
</html>

Dette xml vil jeg gerne via xsl have spyttet ud i en tro kopi.

MEN jeg vil forinden gerne have mulighed for at gøre noget ved samtlige <td>tags - f.eks. tilføje attributten align="center". Samt gøre noget ved samtlige <td>tags med attributten id - f.eks. tilføje teksten kr. efter tallet i <td>tag'et, så der står '500 kr.', '150 kr.' etc..

Hvordan gør jeg det simpelt? I ovenstående kan jeg se de enkelte elementers navne, men jeg vil gerne have at dokumentet bliver gennemløbet og kopieret for hver enkelt element - og manipuleret med, når en af (ovenstående) undtagelser nås.

Nogle gode - og simple - forslag til, hvordan jeg tager hul på den opgave?

Venligst
Marianne
Avatar billede marrix Juniormester
13. oktober 2005 - 09:10 #1
...dokumentet skal gennemløbes og kopieres uanset elementernes antal, navne etc. Kun  <td>tags'ene skal der gøres noget ved.

Marianne
Avatar billede janegil Nybegynder
13. oktober 2005 - 09:58 #2
Se http://www.w3.org/TR/xslt#copying for kode som kopierer det hele:
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

Deretter skriver du en template som matcher td for å gi td'er spesialbehandling.
Avatar billede marrix Juniormester
13. oktober 2005 - 10:07 #3
Tja ... jo ... men "@*|node()" fordrer vist et krav om en attribut, eller hvad?!? Jeg prøver lige. Og hvordan med <xsl:apply-templates select="@*|node()"/> ... hvis vi forudsætter, at den tager alle noderne med, bliver <td>'erne så ikke gentaget dobbelt, hvis jeg efterfølgende gør noget mere ved dem?

Venligst
Marianne
Avatar billede marrix Juniormester
13. oktober 2005 - 10:14 #4
... og hvordan skriver jeg en template som snupper fat i <td>erne?

Jeg har nu forsøgt mig med følgende - hvor jeg bruger et <test>Hej</test> i stedet for <td> ... for at gøre det lidt nemt at starte op på:

    <xsl:template match="@*|node()">
          <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:apply-templates select="test" />
    </xsl:template>       

    <xsl:template match="test">
            <p><xsl:value-of select="."/> og hallo</p>
    </xsl:template>

Fidusen skulle jo så være, at der i output står 'Hej og hallo'. Men <test> bliver åbenbart ikke fanget, så der står forstat bare 'Hej'. Hvad gør jeg forkert?
Avatar billede janegil Nybegynder
13. oktober 2005 - 10:14 #5
Nei, ikke dobbelt. Hvis du har både match="*" og match="td", så er det bare den siste som behandler td, stjerna må nøye seg med det som er igjen etter at mere kresne tempates har forsynt seg.
Avatar billede marrix Juniormester
13. oktober 2005 - 11:05 #6
Men jeg kan ikke få det ovenstående til at virke - enten bliver

    <xsl:apply-templates select="test" />

ignoreret. Eller også er der en fejl i

    <xsl:template match="test">
            <p><xsl:value-of select="."/> og hallo</p>
    </xsl:template>

Hvad går galt?

Venligst
Marianne
Avatar billede janegil Nybegynder
13. oktober 2005 - 11:21 #7
Jeg kjørte

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:apply-templates select="test"/>
    </xsl:template>
    <xsl:template match="td">
        <p>
            <xsl:value-of select="."/> og hallo
        </p>
    </xsl:template>
</xsl:stylesheet>

gjennom XMLSpy, og fikk et resultat som du vil ha det.

Bruker du et foreldet namespace?

Hvilken prosessor bruker du til å lage transformasjonen? Server eller browser eller noe helt annet?
Avatar billede Slettet bruger
13. oktober 2005 - 11:57 #8
Den specifikke apply-templates på test inde i den generelle template skal ud - "test" template'en bliver automatisk apply'et når tid er (medmindre en anden template forhindrer processoren i at fortsætte).

Prøv den her:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="td">
  <xsl:copy>
    <xsl:attribute name="align">center</xsl:attribute>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="table">
  <xsl:copy>
    <xsl:attribute name="border">2</xsl:attribute>
    <xsl:attribute name="width">300</xsl:attribute>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
Avatar billede Slettet bruger
13. oktober 2005 - 12:04 #9
- Husk forresten at id-attributter skal være unikke; Hvis du vil bruge CSS til at "smukificere" tabellen med, skal du nok bruge class-attributten i stedet for (men det er selvfølgelig en helt anden diskussion :-)
Avatar billede marrix Juniormester
13. oktober 2005 - 15:31 #10
Øv ... jeg har prøvet både det ene og det andet - men jeg bliver ved med blot at få "Hej" som output (iht. ovenstående burde jeg jo få "Hej og hallo").

Namespace ... i mit står der
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

Processor ... det er taget ud af en større sammenhæng, men jeg forsøger at holde det simpelt ... det er vist en IBMparser af en eller anden art (arbejder i WebSphere Studio Appl. etc.).

... så namespace't er vel ok. Men hvorfor <xsl:transform ... og ikke <xsl:stylesheet ... hvad er forskellen, og har det nogen betydning?

Jeg forsøger lige at rode lidt videre ... Gode ideer er velkomne :c)

Venligst
Marianne
Avatar billede janegil Nybegynder
14. oktober 2005 - 12:14 #11
http://www.w3.org/TR/xslt#stylesheet-element :

»xsl:transform is allowed as a synonym for xsl:stylesheet«

...og er i mange sammenhenger en bedre beskrivelse
Avatar billede marrix Juniormester
14. oktober 2005 - 14:05 #12
janegil, tak :c)

Jeg pusler stadig, men kan ikke helt få det til at virke....
Avatar billede janegil Nybegynder
14. oktober 2005 - 15:02 #13
Bruk IE eller Firefox til å se om de gir samme resultat som WebSphere. Så finner vi ut om det er WebSphere eller din XSLT-kode som er problemet.

Dette tester du ved å angi stilark i starten av XML'en, se eksempel på http://heima.olivant.fo/~styrheim/xml/prisliste/prisliste.xml .

I Firefox ser du transformasjonsresultatet med ctrl+A > høyreklikk > View selection source.

I IE skal du installere http://heima.olivant.fo/~styrheim/tools/iexmltls.exe, se dokumentasjon på http://heima.olivant.fo/~styrheim/tools/iexmltls.html. Så virker høyreklikket der også.
Avatar billede marrix Juniormester
15. oktober 2005 - 18:02 #14
...lidt svært at trække min xsl-kode ud og teste det i en anden sammenhæng - det jeg pusler med bliver efterfølgende parset/transformeret endnu en gang. Men dette er, hvad jeg indtil tester med:

      <xsl:template match="@*|node()">
            <xsl:copy>
                  <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
      </xsl:template>

      <xsl:template match="p">
            <xsl:copy>
                  <xsl:value-of select="." />
                  <xsl:text>og davs</xsl:text>
                  <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
      </xsl:template>

... således burde vel alle mine <p>er vel få et 'og davs' tilføjet i slutningen. Men jeg kan ikke få det til at virke. Men jeg opgi'r ikke ... :c)

Venligst
Marianne
Avatar billede janegil Nybegynder
15. oktober 2005 - 23:54 #15
<xsl:template match="p">
          <p>
                  <xsl:value-of select="." />
                  <xsl:apply-templates />
                  <xsl:text>- og davs</xsl:text>
          </p>
      </xsl:template>
Avatar billede marrix Juniormester
16. oktober 2005 - 07:52 #16
...okay, prøver ... :c)
Avatar billede marrix Juniormester
16. oktober 2005 - 08:34 #17
Jeg kan stadig ikke få den til at reagere på 'p', men hvis jeg gør følgende:

    <xsl:template match="@*|node()">
        <p>
            <xsl:value-of select="node()" />
            <xsl:apply-templates />
            <xsl:text>- og davs</xsl:text>
        </p>
    </xsl:template>

...så bliver alt indhold lavet om til <p>tags med '- og davs' efter. Så der er altså 'hul igennem' ... men 'match="p"' kan jeg stadig ikke få til at virke.
Avatar billede marrix Juniormester
16. oktober 2005 - 08:39 #18
Hvordan skal @*|node() forstås?
Avatar billede janegil Nybegynder
17. oktober 2005 - 10:04 #19
http://www.w3.org/TR/xslt#section-Defining-Template-Rules#patterns

ALtså alle attributter, alle elementer, alle tekstnoder og muligens enda noe mere.
Avatar billede marrix Juniormester
17. oktober 2005 - 12:37 #20
... tak :c)

Et skridt videre - ikke mod en løsning men en forståelse: Mit xml-dokument bliver åbenbart opfattet som en stor klump, og kun den første node bliver behandlet iht. følgende:

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <p>
            <xsl:value-of select="." />
            <!--xsl:apply-templates /-->
            <xsl:text>- og davs</xsl:text>
        </p>
    </xsl:template>

...så alt indhold på siden (<p>,<div>,<table> etc.) bliver præsenteret som én samlet klump (<p>...</p>) med et '- og davs' i slutningen. Xml-sidens første node er <section>, som vi bruger i den sammenhæng jeg arbejder.

Så som én samlet klump bliver der ikke kigget efter <p>tags ... Mystisk.

VH
Marianne
Avatar billede marrix Juniormester
17. oktober 2005 - 12:41 #21
... har også prøvet med:

    <xsl:template match="p">
        <p>...

og

    <xsl:template match="//p">
        <p>...

Men så er der ingen ændringer ift. det oprindelige dokument - en tro kopi.
Avatar billede marrix Juniormester
17. oktober 2005 - 13:37 #22
"Xml-sidens første node er <section>, som ...". Ævl - glem det. Men jeg har trukket navnet på den node, som ovenstående tilsyneladende tager udgangspunkt i, og det er 'html' ... men hvorfor h.... der ikke bliver skelet til html's children/grandchildren mv. men hele noden bliver opfattet som en eneste klump (for sådan virker det), ved jeg ikke.
Avatar billede janegil Nybegynder
17. oktober 2005 - 14:02 #23
Den template som genererer p skal også matche p.

Når du har både match="@*|node()" og match="p", er det sistnevnte som skal håndtere p-elementet ditt, jeg synes det ser ut som om prosessoren din svikter der. Prøve å flytte matchen på p opp over matchen på @*|node()?

Avsnittet om conflict resolution, http://www.w3.org/TR/xslt#conflict er totalt uleselig, prøv å finne bedre dokumentasjon annetsteds.
Avatar billede marrix Juniormester
17. oktober 2005 - 14:52 #24
Nu har jeg forsøgt at kigge i nogle af de øvrige xsl'er i projektet. Det er ikke så ofte, at vi trækker eks. <p> ud (de bliver oftest tilføjet i xsl'en), men det ene sted jeg fandt et eksempel på et <h>, så det således ud:

match="x2:h" og henviser vel til ns'et:     xmlns:x2="http://www.w3.org/2002/06/xhtml2"

... men hvordan skal det så forstås?

NB! janegil og greystate ... I har vel efterhånden svaret på mit oprindelige spørgsmål - at det ikke virker i det miljø, jeg arbejder i, er jo ikke jeres skyld. Er det ok, hvis I deles om points?

VH
Marianne
Avatar billede janegil Nybegynder
17. oktober 2005 - 15:18 #25
x2:h er en overskrift som selv finner ut av hvor store typer den skal ha. Men ditt problem er i XML, det spiller ingen rolle hvilke html-elementer du strir med.

Dette kunne lyde som en support-sak til IBM?

Eller som at du må droppe
match="@*|node()"
og heller prøve
match="@*|*|text()"

Eller at du skal be om å få en oppgradering av XSLT-prosessoren i webshere.
Avatar billede Slettet bruger
17. oktober 2005 - 21:26 #26
For mig lyder det som om din match="p" skal have namespace-prefixet med, altså match="x2:p" - det kan ihvertfald forklare hvorfor den ikke har reageret før...

/CS
Avatar billede marrix Juniormester
18. oktober 2005 - 09:51 #27
HAHAHA! Så lykkedes det ... namespace-prefixet gjorde forskellen. Den efterfølgende behandling/tranformation (som jeg ikke er herre over) SKAL åbenbart have det her ns med. Nu virker det. Tak for hjælpen til jer begge ... og som tidligere forespurgt: I har hjulpet meget begge to, og for længst svaret på mit oprindelige spørgsmål ... kan I leve med at deles om pointene?

Venligst - og beruset af lykke :c)
Marianne
Avatar billede Slettet bruger
18. oktober 2005 - 09:55 #28
Tillykke med "sejren" Marianne :-)

Mht. point: Det er vidst ikke første gang vi har delt point, vel janegil? :-)
Avatar billede marrix Juniormester
18. oktober 2005 - 15:08 #29
...den der tier samtykker (eller er for sent ude til at have en mening ;c)): Håber det er ok, janegil, mht. at dele med greystate - I har jo tilsyneladende prøvet det før.

Tusind tak for hjælpen til jer begge.

Venligst
Marianne
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