xslt: normale countvariable

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • xslt: normale countvariable

    Hallo!

    Wie implementiert man in XSLT am besten ein Counter. Geht ja ned wirklich da variablen irgendwie statisch sind.

    Mein Problem:
    Ich habe eine If Abfrage in einer for-Schleife und immer wenn diese true liefert soll Switch_XXXX ausgegeben werden wobei XXXX aufsteigend nummeriert werden soll also:
    Switch_0000
    Switch_0001
    Switch_0002
    .
    .
    .
    Wie löst man das am besten??

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Apfelstrudl ()

  • ich kann dir hierzu nur eine sehr gute Antwort zitieren:

    sources.redhat.com/ml/xsl-list/2001-10/msg00274.html
    1. Will <xsl:number> suffice? See w3.org/TR/xslt#number.

    2. If <xsl:number> won't do, and you are counting nodes, or any
    characteristics that can be determined about nodes, you might be able to use
    the count() function on a suitable node-set (specified with an appropriate
    XPath expression). Or in some contexts you can use the position() function.

    3. If neither of options 1 or 2 is suitable, you can probably count what you
    want by using a recursive named template. I won't give an example here,
    since I don't know if it is appropriate for your problem. But this is about
    the only way you can do something like: $matchNumber = $matchNumber + 1
    (without using extensions).

    I can answer the first part of your question: no, variable bindings in XSLT
    are scoped to the following siblings (and their descendants) of the element
    in which they are "declared" with <xsl:variable>. Once declared, the values
    cannot be changed. You could have identically named variables in every
    template in your stylesheet if you wanted, and they would all be distinct.
    You can have top-level bindings that are visible everywhere, but the values
    can't be changed anywhere else.


    Du solltest versuchen dein Vorhaben mit XSLT Mitteln zu lösen. Das würde bedeuten das ganze in einen XPATH Ausdruck zu packen.
    Alternativ bleiben dir nur Workarounds wie das rekursive Template.

    Vielleicht weiß ja "xml_looser" einen Rat.
  • d0nut schrieb:

    ich kann dir hierzu nur eine sehr gute Antwort zitieren:
    sources.redhat.com/ml/xsl-list/2001-10/msg00274.html
    ...
    Du solltest versuchen dein Vorhaben mit XSLT Mitteln zu lösen. Das würde bedeuten das ganze in einen XPATH Ausdruck zu packen.

    Das kannte ich schon, habe mir daher eh schon vorher darüber Gedanken gemacht. Leider wüsste ich nicht wie ich das machen sollte. Vielleicht kannst ja du mir auf die Sprünge helfen.

    Quellcode

    1. <config>
    2. <routerlist>
    3. <router id="1" promiscuous="on">
    4. <belongsto>1</belongsto>
    5. <belongsto>2</belongsto>
    6. <belongsto>3</belongsto>
    7. <belongsto>4</belongsto>
    8. <in>1/2/2</in>
    9. </router>
    10. </routerlist>
    11. <devicelist>
    12. <device id="1" promiscuous="on">
    13. <belongsto>4</belongsto>
    14. <inout>1/2/2</inout>
    15. </device>
    16. <device id="2" promiscuous="on">
    17. <belongsto>4</belongsto>
    18. <belongsto>3</belongsto>
    19. <inout>1/2/2</inout>
    20. </device>
    21. <device id="3" promiscuous="on">
    22. <belongsto>3</belongsto>
    23. <inout>1/2/2</inout>
    24. </device>
    25. </devicelist>
    26. </config>
    Alles anzeigen

    Aufgabe: zu jedem belongsto - eindeutige Nummer (hier in diesem fall 1,2,3,4) - die Häufigkeit ermitteln. Wenn es pro Nummer mehr als 2 Vorkommen gibt dann Counter Wert ausgeben und diesen dann um 1 erhöhen.

    Da nur die Nummern 3 und 4 öfters als 2mal auftreten sollte die Ausgabe so aussehen.
    Switch_0000
    Switch_0001


    d0nut schrieb:


    Alternativ bleiben dir nur Workarounds wie das rekursive Template.

    Brauche ich das in meinem Fall?
  • Hallo Apfelstrudel
    bezogen auf

    XML-Quellcode

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <config>
    3. <routerlist>
    4. <router id="1" promiscuous="on">
    5. <belongsto>1</belongsto>
    6. <belongsto>2</belongsto>
    7. <belongsto>3</belongsto>
    8. <belongsto>4</belongsto>
    9. <in>1/2/2</in>
    10. </router>
    11. </routerlist>
    12. <devicelist>
    13. <device id="1" promiscuous="on">
    14. <belongsto>4</belongsto>
    15. <inout>1/2/2</inout>
    16. </device>
    17. <device id="2" promiscuous="on">
    18. <belongsto>4</belongsto>
    19. <belongsto>3</belongsto>
    20. <inout>1/2/2</inout>
    21. </device>
    22. <device id="3" promiscuous="on">
    23. <belongsto>3</belongsto>
    24. <inout>1/2/2</inout>
    25. </device>
    26. </devicelist>
    27. </config>
    Alles anzeigen


    HTML-Quellcode

    1. <?xml version="1.0"?>
    2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3. <xsl:output indent="yes" method="html"/>
    4. <xsl:key name="only" match="//devicelist//belongsto" use="."/>
    5. <xsl:template match="/">
    6. <html>
    7. <table border="2px solid" >
    8. <tr>
    9. <th>belongto</th>
    10. <th>nr</th>
    11. </tr>
    12. <xsl:apply-templates select="config/devicelist"/>
    13. </table>
    14. </html>
    15. </xsl:template>
    16. <xsl:template match="devicelist">
    17. <xsl:for-each select="//belongsto[generate-id()= generate-id(key('only', .)[1])]">
    18. <xsl:sort/>
    19. <tr>
    20. <td>
    21. <xsl:value-of select="."/>
    22. </td>
    23. <td>
    24. <!--
    25. <xsl:value-of select="count(key('only',.))"/>
    26. -->
    27. <xsl:call-template name="ausgabe">
    28. <xsl:with-param name="kn" select="key('only',.)"></xsl:with-param>
    29. </xsl:call-template>
    30. </td>
    31. </tr>
    32. </xsl:for-each>
    33. </xsl:template>
    34. <xsl:template name="ausgabe">
    35. <xsl:param name="kn"></xsl:param>
    36. <table>
    37. <xsl:for-each select="$kn">
    38. <tr>
    39. <td>
    40. <xsl:variable name="len" select="concat(substring('0000',string-length(position())+1,4),position())"></xsl:variable>
    41. <xsl:value-of select="concat('Switch_',$len)"/>
    42. </td>
    43. </tr>
    44. </xsl:for-each>
    45. </table>
    46. </xsl:template>
    47. </xsl:stylesheet>
    Alles anzeigen


    ergebnis

    HTML-Quellcode

    1. <html>
    2. <table border="2px solid">
    3. <tr>
    4. <th>belongto</th>
    5. <th>nr</th>
    6. </tr>
    7. <tr>
    8. <td>3</td>
    9. <td>
    10. <table>
    11. <tr>
    12. <td>Switch_0001</td>
    13. </tr>
    14. <tr>
    15. <td>Switch_0002</td>
    16. </tr>
    17. </table>
    18. </td>
    19. </tr>
    20. <tr>
    21. <td>4</td>
    22. <td>
    23. <table>
    24. <tr>
    25. <td>Switch_0001</td>
    26. </tr>
    27. <tr>
    28. <td>Switch_0002</td>
    29. </tr>
    30. </table>
    31. </td>
    32. </tr>
    33. </table>
    34. </html>
    Alles anzeigen
    Helmut Hagemann
    Derjenige, der sagt: Das geht nicht, soll den nicht stören, der's gerade tut.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von xml_looser ()

  • Hallo!

    Herzlichsten Dank für deinen HilfeVersuch. Leider scheinst du nicht ganz die Aufgabe verstanden zu haben.
    Was mir aufgefallen ist: du wendest das template nur auf die Devices an -> das habe ich aber nirgends erwähnt. Es sollen ALLE belongsto im gesamten file berücksichtigt werden, unabhängig von der Position im File.
    Außerdem glaube ich das noch irgendwas nicht stimmt, denn warum gibst du zweimal Switch_0001 und Switch_0002 aus?
    Außerdem fehlt mir eine Abfrage die prüft ob eine bestimmter belongsto value öfters als 2mal vorkommt. Wie prüfst du das??

    Ich versuche nochmal das Problem zu beschreiben (leicht geändertes XML File):

    Quellcode

    1. <config>
    2. <routerlist>
    3. <router id="1" promiscuous="on">
    4. <belongsto>1</belongsto>
    5. <belongsto>2</belongsto>
    6. <belongsto>4</belongsto>
    7. <belongsto>5</belongsto>
    8. <in>1/2/2</in>
    9. </router>
    10. </routerlist>
    11. <devicelist>
    12. <device id="1" promiscuous="on">
    13. <belongsto>4</belongsto>
    14. <inout>1/2/2</inout>
    15. </device>
    16. <device id="2" promiscuous="on">
    17. <belongsto>3</belongsto>
    18. <belongsto>4</belongsto>
    19. <inout>1/2/2</inout>
    20. </device>
    21. <device id="3" promiscuous="on">
    22. <belongsto>1</belongsto>
    23. <inout>1/2/2</inout>
    24. </device>
    25. </devicelist>
    26. </config>
    Alles anzeigen


    Ich habe insgesamt 8 belongsto tags. (4 belongsto beim ersten Router, 1 belongsto beim ersten device, 2 belongsto beim zweiten device, 1 belongsto beim dritten device)

    Nun zähle ich zu jedem belongsto Wert die Häufigkeit.
    der Wert 1 kommt 2 mal vor -> 2 ist nicht größer 2 daher kein Switch
    der Wert 2 kommt 1 mal vor -> 1 ist nicht größer 2 daher kein Switch
    der Wert 3 kommt 1 mal vor -> 1 ist nicht größer 2 daher kein Switch
    der Wert 4 kommt 3 mal vor -> 3 ist größer als zwei daher ein Switch
    der Wert 5 kommt 1 mal vor -> 1 ist nicht größer 2 daher kein Switch
    --------------------------------------------------------------------------------------
    Kontrolle: 2+1+1+3+1 = 8

    Insgesamt soll dann sowas am Bildschirm stehen:
    Switch_0001
  • Hallo Apfelstrudel

    bin kein hellseher

    xml ist für mich Freizeiträstel

    neuer versuch
    xsl

    HTML-Quellcode

    1. <?xml version="1.0"?>
    2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3. <xsl:output indent="yes" method="html"/>
    4. <xsl:key name="only" match="//belongsto" use="."/>
    5. <xsl:key name="onlyyou" match="//belongsto[1][text()=//preceding-sibling::*//belongsto/text()][count(key('only',.))&gt;2]" use="."/>
    6. <xsl:template match="/">
    7. <html>
    8. <table border="2px solid">
    9. <tr>
    10. <th>belongto</th>
    11. <th>nr</th>
    12. </tr>
    13. <xsl:apply-templates select="config/devicelist"/>
    14. </table>
    15. </html>
    16. </xsl:template>
    17. <xsl:template match="devicelist">
    18. <xsl:for-each select="//belongsto[generate-id()= generate-id(key('only', .)[1])]">
    19. <xsl:sort/>
    20. <tr>
    21. <td>
    22. <xsl:value-of select="."/>
    23. </td>
    24. <td>
    25. <xsl:value-of select="count(key('only',.))"/>
    26. </td>
    27. </tr>
    28. </xsl:for-each>
    29. <!--
    30. <xsl:call-template name="ausgabe">
    31. <xsl:with-param name="kn" select="//belongsto[1][text()=//preceding-sibling::*//belongsto/text()][count(key('only',.))&gt;2]"/>
    32. </xsl:call-template>
    33. -->
    34. <xsl:call-template name="ausgabe1">
    35. <xsl:with-param name="kn" select="//belongsto[1][text()=//preceding-sibling::*//belongsto/text()][count(key('only',.))&gt;2]"/>
    36. </xsl:call-template>
    37. </xsl:template>
    38. <xsl:template name="ausgabe">
    39. <xsl:param name="kn"></xsl:param>
    40. <table>
    41. <caption>aus0</caption>
    42. <xsl:for-each select="$kn">
    43. <tr>
    44. <td>
    45. <xsl:variable name="len" select="concat(substring('0000',string-length(position())+1,4),position())"></xsl:variable>
    46. <xsl:value-of select="concat('Switch_',$len,' ',.)"/>
    47. </td>
    48. </tr>
    49. </xsl:for-each>
    50. </table>
    51. </xsl:template>
    52. <xsl:template name="ausgabe1">
    53. <xsl:param name="kn"></xsl:param>
    54. <table border="2px solid red" >
    55. <caption>aus1 <xsl:value-of select="concat('Lösung',' ','gefunden')"/></caption>
    56. <xsl:for-each select="$kn[generate-id()= generate-id(key('onlyyou', .)[1])]">
    57. <tr>
    58. <td>
    59. <xsl:variable name="len" select="concat(substring('0000',string-length(position())+1,4),position())"></xsl:variable>
    60. <xsl:value-of select="concat('Switch_',$len,' ',.)"/>
    61. </td>
    62. </tr>
    63. </xsl:for-each>
    64. </table>
    65. </xsl:template>
    66. </xsl:stylesheet>
    Alles anzeigen


    Idee war position() als Zähler zubenutzen

    zusammen setzen einer node list und key Einzigartigkeit erzeugen
    xsl:key ist sehr mächtig und übergreifend auf alle gewählten Knoten
    lösung tabelle aufgeliste belongsto mit anzahl und Zähler der switches welecher belongsto drei übersteigt

    HTML-Quellcode

    1. <html>
    2. <table border="2px solid">
    3. <tr>
    4. <th>belongto</th>
    5. <th>nr</th>
    6. </tr>
    7. <tr>
    8. <td>1</td>
    9. <td>2</td>
    10. </tr>
    11. <tr>
    12. <td>2</td>
    13. <td>1</td>
    14. </tr>
    15. <tr>
    16. <td>3</td>
    17. <td>1</td>
    18. </tr>
    19. <tr>
    20. <td>4</td>
    21. <td>3</td>
    22. </tr>
    23. <tr>
    24. <td>5</td>
    25. <td>1</td>
    26. </tr>
    27. <table border="2px solid red">
    28. <caption>aus1 Lösung gefunden</caption>
    29. <tr>
    30. <td>Switch_0001 4</td>
    31. </tr>
    32. </table>
    33. </table>
    34. </html>
    Alles anzeigen


    hoffe jetzt ist Lösung da
    freue mich über eine Rückmeldung
    Helmut Hagemann
    Derjenige, der sagt: Das geht nicht, soll den nicht stören, der's gerade tut.