XSLT preceding problem

Discussion in 'XML' started by Sven, Jul 7, 2003.

  1. Sven

    Sven Guest

    Hi

    I have the following XML & XSLT:

    XML:
    <?xml version="1.0" encoding="utf-8"?>

    <Source Source="IBM">
    <Detail>
    <UserID></UserID>
    <Time>20030610135531</Time>
    <ActionCode>IBM421</ActionCode>
    <ActionText>Start sessie</ActionText>
    <ChargingID>0750490000011325</ChargingID>
    </Detail>

    <Detail>
    <UserID>31622000658</UserID>
    <Time>20030610135532</Time>
    <ActionCode>IBM420</ActionCode>
    <ActionText>Succesvolle account balance wijziging</ActionText>
    <ChargingID>0750490000011325</ChargingID>
    </Detail>

    <Detail>
    <UserID>time-trigger</UserID>
    <Time>20030613235901</Time>
    <ActionCode>IBM440</ActionCode>
    <ActionText>rapport 1</ActionText>
    <ChargingID></ChargingID>
    </Detail>

    <Detail>
    <UserID>time-trigger</UserID>
    <Time>20030613235902</Time>
    <ActionCode>IBM443</ActionCode>
    <ActionText>Rapport 3</ActionText>
    <ChargingID></ChargingID>
    </Detail>

    </Source>


    XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput method="xml" version="1.0" encoding="ISO-8859-1"
    indent="yes"/>

    xsl:param name="action_codes" select="',420,421,422,430,431,432,'"/>
    <xsl:template match="/">

    <xsomething>
    <data_details>
    <xsl:for-each select="Source/Detail[(contains($action_codes,concat(',',substring(ActionCode,4,3),',')))]">
    <xsl:sort select="Time" order="ascending"/>

    <data_detail>
    <xsl:if test="string-length(UserID) != 0">
    <user_id><xsl:value-of select="UserID"/></user_id>
    </xsl:if>

    <datum_record>
    <xsl:value-of select="substring(Time,1, 4)"/>-<xsl:value-of
    select="substring(Time, 5, 2)"/>-<xsl:value-of select="substring(Time,
    7, 2)"/>T<xsl:value-of select="substring(Time, 9, 2)"/>:<xsl:value-of
    select="substring(Time, 11, 2)"/>:<xsl:value-of
    select="substring(Time, 13, 2)"/>
    </datum_record>

    <action_code><xsl:value-of select="ActionCode"/></action_code>

    <action_tekst><xsl:value-of select="ActionText"/></action_tekst>

    <xsl:if test="string-length(ChargingID) != 0">
    <charging_id><xsl:value-of select="ChargingID"/></charging_id>
    </xsl:if>

    <xsl:if test="string-length(ChargingID) = 0">
    <charging_id><xsl:value-of
    select="normalize-space(preceding::ChargingID[1])"/></charging_id>
    </xsl:if>
    </data_detail>

    </xsl:for-each>
    </data_details>
    </xsomething>

    </xsl:template>
    </xsl:stylesheet>

    The goal of my xslt is, that when the tag CHARGING_ID is missing that
    the previously known charging_id will be used. Sometimes it will be
    the previous another time it will be 10 'records' back.

    Unfortunately the XSLT above is not working correctly, because when
    the value of Charging_id is not present the tag will be supplied (I
    cannot change it).

    Is there another way to achieve my goal, by ie. changing this piece of
    code 'preceding::ChargingID[1]'?
    I have tried recursive templates but I didnt figured it out ?

    Anyone an idea ?

    greets
    Sven
    Sven, Jul 7, 2003
    #1
    1. Advertising

  2. Sven

    Marrow Guest

    Hi Sven,

    I think you are almost there...

    If you change...
    <xsl:value-of select="normalize-space(preceding::ChargingID[1])"/>
    to...
    <xsl:value-of select="preceding::ChargingID[normalize-space()][1]"/>

    Although rather than two opposing <xsl:if>'s you might be better with a
    <xsl:choose>, e.g.

    <charging_id>
    <xsl:choose>
    <xsl:when test="normalize-space(ChargingID)">
    <xsl:value-of select="ChargingID"/>
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:value-of
    select="preceding::ChargingID[normalize-space()][1]"/>
    </xsl:eek:therwise>
    </xsl:choose>
    </charging_id>

    Or you could roll it into one XPath expression, something like...

    <charging_id>
    <xsl:value-of select="(ChargingID[normalize-space()] |
    preceding-sibling::Detail[normalize-space(ChargingID)][1]/ChargingID)[last()
    ]"/>
    </charging_id>

    BTW, if you replace this bit of code...

    <datum_record>
    <xsl:value-of select="substring(Time,1, 4)"/>-<xsl:value-of
    select="substring(Time, 5, 2)"/>-<xsl:value-of select="substring(Time,
    7, 2)"/>T<xsl:value-of select="substring(Time, 9, 2)"/>:<xsl:value-of
    select="substring(Time, 11, 2)"/>:<xsl:value-of
    select="substring(Time, 13, 2)"/>
    </datum_record>

    with...

    <datum_record>
    <xsl:value-of select="substring(Time,1, 4)"/>
    <xsl:text>-</xsl:text>
    <xsl:value-of select="substring(Time, 5, 2)"/>
    <xsl:text>-</xsl:text>
    <xsl:value-of select="substring(Time, 7, 2)"/>
    <xsl:text>T</xsl:text>
    <xsl:value-of select="substring(Time, 9, 2)"/>
    <xsl:text>:</xsl:text>
    <xsl:value-of select="substring(Time, 11, 2)"/>
    <xsl:text>:</xsl:text>
    <xsl:value-of select="substring(Time, 13, 2)"/>
    </datum_record>

    you won't have to run all the lines of XSLT code together in order to avoid
    CR/LFs from appearing in the <datum_record> output element value.

    Hope this helps
    Marrow
    http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
    http://www.topxml.com/Xselerator


    "Sven" <> wrote in message
    news:...
    > Hi
    >
    > I have the following XML & XSLT:
    >
    > XML:
    > <?xml version="1.0" encoding="utf-8"?>
    >
    > <Source Source="IBM">
    > <Detail>
    > <UserID></UserID>
    > <Time>20030610135531</Time>
    > <ActionCode>IBM421</ActionCode>
    > <ActionText>Start sessie</ActionText>
    > <ChargingID>0750490000011325</ChargingID>
    > </Detail>
    >
    > <Detail>
    > <UserID>31622000658</UserID>
    > <Time>20030610135532</Time>
    > <ActionCode>IBM420</ActionCode>
    > <ActionText>Succesvolle account balance wijziging</ActionText>
    > <ChargingID>0750490000011325</ChargingID>
    > </Detail>
    >
    > <Detail>
    > <UserID>time-trigger</UserID>
    > <Time>20030613235901</Time>
    > <ActionCode>IBM440</ActionCode>
    > <ActionText>rapport 1</ActionText>
    > <ChargingID></ChargingID>
    > </Detail>
    >
    > <Detail>
    > <UserID>time-trigger</UserID>
    > <Time>20030613235902</Time>
    > <ActionCode>IBM443</ActionCode>
    > <ActionText>Rapport 3</ActionText>
    > <ChargingID></ChargingID>
    > </Detail>
    >
    > </Source>
    >
    >
    > XSLT:
    >
    > <?xml version="1.0" encoding="UTF-8"?>
    > <xsl:stylesheet version="1.0"
    > xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    > <xsl:eek:utput method="xml" version="1.0" encoding="ISO-8859-1"
    > indent="yes"/>
    >
    > xsl:param name="action_codes" select="',420,421,422,430,431,432,'"/>
    > <xsl:template match="/">
    >
    > <xsomething>
    > <data_details>
    > <xsl:for-each

    select="Source/Detail[(contains($action_codes,concat(',',substring(ActionCod
    e,4,3),',')))]">
    > <xsl:sort select="Time" order="ascending"/>
    >
    > <data_detail>
    > <xsl:if test="string-length(UserID) != 0">
    > <user_id><xsl:value-of select="UserID"/></user_id>
    > </xsl:if>
    >
    > <datum_record>
    > <xsl:value-of select="substring(Time,1, 4)"/>-<xsl:value-of
    > select="substring(Time, 5, 2)"/>-<xsl:value-of select="substring(Time,
    > 7, 2)"/>T<xsl:value-of select="substring(Time, 9, 2)"/>:<xsl:value-of
    > select="substring(Time, 11, 2)"/>:<xsl:value-of
    > select="substring(Time, 13, 2)"/>
    > </datum_record>
    >
    > <action_code><xsl:value-of select="ActionCode"/></action_code>
    >
    > <action_tekst><xsl:value-of select="ActionText"/></action_tekst>
    >
    > <xsl:if test="string-length(ChargingID) != 0">
    > <charging_id><xsl:value-of select="ChargingID"/></charging_id>
    > </xsl:if>
    >
    > <xsl:if test="string-length(ChargingID) = 0">
    > <charging_id><xsl:value-of
    > select="normalize-space(preceding::ChargingID[1])"/></charging_id>
    > </xsl:if>
    > </data_detail>
    >
    > </xsl:for-each>
    > </data_details>
    > </xsomething>
    >
    > </xsl:template>
    > </xsl:stylesheet>
    >
    > The goal of my xslt is, that when the tag CHARGING_ID is missing that
    > the previously known charging_id will be used. Sometimes it will be
    > the previous another time it will be 10 'records' back.
    >
    > Unfortunately the XSLT above is not working correctly, because when
    > the value of Charging_id is not present the tag will be supplied (I
    > cannot change it).
    >
    > Is there another way to achieve my goal, by ie. changing this piece of
    > code 'preceding::ChargingID[1]'?
    > I have tried recursive templates but I didnt figured it out ?
    >
    > Anyone an idea ?
    >
    > greets
    > Sven
    Marrow, Jul 7, 2003
    #2
    1. Advertising

  3. Sven

    Sven Guest

    Hi Marrow,

    Thank you very much. It works excellent !! Also thanx for the addiditional remarks.

    greets,
    Sven

    "Marrow" <> wrote in message news:<GXfOa.947$%>...
    > Hi Sven,
    >
    > I think you are almost there...
    >
    Sven, Jul 8, 2003
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. nobody
    Replies:
    4
    Views:
    1,342
    nobody
    Feb 15, 2004
  2. Dimitre Novatchev
    Replies:
    2
    Views:
    452
    Dimitre Novatchev [MVP XML]
    Feb 15, 2004
  3. Chris
    Replies:
    5
    Views:
    1,857
    Chris
    Apr 19, 2005
  4. Replies:
    0
    Views:
    487
  5. njsimha
    Replies:
    0
    Views:
    777
    njsimha
    Sep 16, 2008
Loading...

Share This Page