XSLT - removing a tag from within text

Discussion in 'XML' started by gwoodhouse@gmail.com, Jun 17, 2009.

  1. Guest

    Hi All,

    This should be so easy but is so incredibly not easy that im about
    ready to kill myself.

    What i have is this xml:
    <node>
    <start_time>00:00:<span class="hit">11</span></start_time>
    </node>

    and i just want it to output:
    00:00:00

    Luckily for me XSLT is ridiculous, making this problem unsolvable.

    i've tried:
    fn:substring-before(start_time, "<")
    but of course, thats far too straight forward so it doesnt work.

    I've tried:
    <xsl:apply-templates select="start_time"/>
    <xsl:template match="span">
    </xsl:template>
    but of course, that, although esoteric, doesn't work either

    I've tried string(start_time), i've even tried to do fn:escape-uri and
    tried to replace those values but that doesnt work either!

    Please someone for the love of all that is good in this world help
    me!!!!!
     
    , Jun 17, 2009
    #1
    1. Advertising

  2. Guest

    Sorry, the output should be 00:00:11 in that case.
     
    , Jun 17, 2009
    #2
    1. Advertising

  3. wrote:

    > What i have is this xml:
    > <node>
    > <start_time>00:00:<span class="hit">11</span></start_time>
    > </node>
    >
    > and i just want it to output:
    > 00:00:00


    This is easy:

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

    <xsl:eek:utput method="text"/>

    <xsl:template match="/">
    <xsl:apply-templates select="node/start_time"/>
    </xsl:template>

    </xsl:stylesheet>


    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Jun 17, 2009
    #3
  4. Martin Honnen a écrit :
    > wrote:
    >
    >> What i have is this xml:
    >> <node>
    >> <start_time>00:00:<span class="hit">11</span></start_time>
    >> </node>
    >>
    >> and i just want it to output:
    >> 00:00:00

    >
    > This is easy:
    >
    > <xsl:stylesheet
    > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    > version="1.0">
    >
    > <xsl:eek:utput method="text"/>
    >
    > <xsl:template match="/">
    > <xsl:apply-templates select="node/start_time"/>
    > </xsl:template>
    >
    > </xsl:stylesheet>


    this one should work too:

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

    <xsl:eek:utput method="text"/>

    </xsl:stylesheet>

    --
    Cordialement,

    ///
    (. .)
    --------ooO--(_)--Ooo--------
    | Philippe Poulard |
    -----------------------------
    http://reflex.gforge.inria.fr/
    Have the RefleX !
     
    Philippe Poulard, Jun 17, 2009
    #4
  5. Guest

    Ok, so, i can't include the whole code or else my company would beat
    the hell out of me. Here is a more complete and realworld snippet:

    <transcript>
    <chapter>
    <chapter_hitcount><![CDATA[1 hit]]></chapter_hitcount>
    <start_time><![CDATA[01:11:04]]></start_time>
    <end_time><![CDATA[01:<span class="hit">22</span>:45]]></end_time>
    <abstract> You can see here how you would want <span
    class="hit">22</span> to be displayed</abstract>
    </chapter>
    </transcript>

    xslt:
    <xsl:template match='chapter'>
    <span class="timespan">
    (<xsl:apply-templates select="start_time"/> - <xsl:apply-templates
    select="end_time"/>)
    </span>
    <div class="abstract">
    <span class="abstractLead">Summary:</span> <xsl:apply-templates
    select="abstract"/>
    </div>
    </xsl:template>

    In this example i would want the output to display the "abstract"
    output with the span tag, i would want the "end_time" tag to display
    without the <span> tag.
     
    , Jun 17, 2009
    #5
  6. Philippe Poulard wrote:
    > Martin Honnen a écrit :
    >> wrote:
    >>
    >>> What i have is this xml:
    >>> <node>
    >>> <start_time>00:00:<span class="hit">11</span></start_time>
    >>> </node>
    >>>
    >>> and i just want it to output:
    >>> 00:00:00


    > this one should work too:
    >
    > <xsl:stylesheet
    > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    > version="1.0">
    >
    > <xsl:eek:utput method="text"/>
    >
    > </xsl:stylesheet>


    That would output additional white space.

    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Jun 17, 2009
    #6
  7. wrote:
    > Ok, so, i can't include the whole code or else my company would beat
    > the hell out of me. Here is a more complete and realworld snippet:
    >
    > <transcript>
    > <chapter>
    > <chapter_hitcount><![CDATA[1 hit]]></chapter_hitcount>
    > <start_time><![CDATA[01:11:04]]></start_time>
    > <end_time><![CDATA[01:<span class="hit">22</span>:45]]></end_time>
    > <abstract> You can see here how you would want <span
    > class="hit">22</span> to be displayed</abstract>
    > </chapter>
    > </transcript>
    >
    > xslt:
    > <xsl:template match='chapter'>
    > <span class="timespan">
    > (<xsl:apply-templates select="start_time"/> - <xsl:apply-templates
    > select="end_time"/>)
    > </span>
    > <div class="abstract">
    > <span class="abstractLead">Summary:</span> <xsl:apply-templates
    > select="abstract"/>
    > </div>
    > </xsl:template>
    >
    > In this example i would want the output to display the "abstract"
    > output with the span tag, i would want the "end_time" tag to display
    > without the <span> tag.


    Well that is completely different from what you posted before and in the
    sample above the 'abstract' element contains a 'span' element while the
    'end_time' element does not contain a 'span' element, instead it
    contains pure text with escaped markup.

    The 'abstract' element can easily be solved with XSLT

    <xsl:template match="abstract">
    <div class="{local-name()}">
    <xsl:apply-templates/>
    </div>
    </xsl:template>

    then you need to add a template matching span that copies that

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

    The 'end_time' element is difficult. If I had a choice I would solve it
    with XSLT 2.0 and David Carlisle's HTML parser done in XSLT
    (http://www.dcarlisle.demon.co.uk/htmlparse.xsl) but I don't know
    whether that is an option for you.



    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Jun 17, 2009
    #7
  8. Guest

    Yeah, problem is none of that works.

    There are lots of places where many many values need to print out a
    <span> tag.

    What i want is a way of removing <span class="hit"> from the output of
    ONE tag.

    Please someone tell me there is a way of doing that, not by changing
    the way everything else works, just by removing the damn <span> tag
    from one output.

    Surely, SURELY, XSLT can manage to create a variable from "a bit of
    <span>text</span>" that contains "a bit of text".

    Surely?!?!
     
    , Jun 17, 2009
    #8
  9. Guest

    So, basically, i want this:

    end_time contents: 00:00:<span class="hit">11</span>

    <xsl:variable name="safeend">
    <xsl:call-template name="removeSpan">
    <xsl:with-param name="variable" select="end_time"/>
    </xsl:call-template>
    </xsl:variable>

    <xsl:template name="removeSpan">
    <xsl:param name="variable"/>
    <xsl:value-of select="fn:substring-before($variable, '<')"/>
    </xsl:template>

    with safeend being: 00:00:11

    Yes it's in a CDATA tag but that doesn't seem to change anything at
    all.
     
    , Jun 17, 2009
    #9
  10. Martin Honnen, Jun 17, 2009
    #10
  11. Guest

    On Jun 17, 2:34 pm, Martin Honnen <> wrote:
    > wrote:
    > > Yeah, problem is none of that works.

    >
    > None of what?


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

    would make a global change to the functionality of the XSLT (not that
    this actually seems to do anything at all even if it did work)

    All i want is a nice simple string/node change. On just one node. When
    i tell it to. Everywhere else in the XSLT it's doing exactly as it
    should, the only thing i need to change is outputting the end_time
    field WITHOUT <span>.
     
    , Jun 17, 2009
    #11
  12. a écrit :
    > On Jun 17, 2:34 pm, Martin Honnen <> wrote:
    >> wrote:
    >>> Yeah, problem is none of that works.

    >> None of what?

    >
    > <xsl:template match="span">
    > <xsl:copy>
    > <xsl:apply-templates select="@* | node()"/>
    > </xsl:copy>
    > </xsl:template>
    >
    > would make a global change to the functionality of the XSLT (not that
    > this actually seems to do anything at all even if it did work)
    >
    > All i want is a nice simple string/node change. On just one node. When
    > i tell it to. Everywhere else in the XSLT it's doing exactly as it
    > should, the only thing i need to change is outputting the end_time
    > field WITHOUT <span>.


    you don't have a <span> node, you just have a <span> text; just use
    string manipulation functions such as substring-before() and
    substring-after() that are available in xslt 1.0 for that purpose

    something like this:

    <xsl:template match='end_time'>
    <xsl:value-of select="substring-before(.,'<span')"/>
    <xsl:value-of
    select="substring-before(substring-after(.,'>'),'</span>'"/>
    <xsl:value-of select="substring-after(.,'</span>')"/>
    </xsl:template>

    very ugly

    --
    Cordialement,

    ///
    (. .)
    --------ooO--(_)--Ooo--------
    | Philippe Poulard |
    -----------------------------
    http://reflex.gforge.inria.fr/
    Have the RefleX !
     
    Philippe Poulard, Jun 17, 2009
    #12
  13. Guest

    > you don't have a <span> node, you just have a <span> text; just use
    > string manipulation functions such as substring-before() and
    > substring-after() that are available in xslt 1.0 for that purpose


    If only it were that easy -

    I get the error message:
    Line #100; Column #57; org.xml.sax.SAXParseException: The value of
    attribute "select" associated with an element type "xsl:value-of" must
    not contain the '<' character.

    and putting &lt; gives a stack overflow exception as it seems to make
    the proccessor recurse continually.
     
    , Jun 17, 2009
    #13
  14. a écrit :
    >> you don't have a <span> node, you just have a <span> text; just use
    >> string manipulation functions such as substring-before() and
    >> substring-after() that are available in xslt 1.0 for that purpose

    >
    > If only it were that easy -
    >
    > I get the error message:
    > Line #100; Column #57; org.xml.sax.SAXParseException: The value of
    > attribute "select" associated with an element type "xsl:value-of" must
    > not contain the '<' character.


    you're right, i forgot to escape it:

    <xsl:template match='end_time'>
    <xsl:value-of select="substring-before(.,'&lt;span')"/>
    <xsl:value-of
    select="substring-before(substring-after(.,'&gt;'),'&lt;/span&gt;'"/>
    <xsl:value-of select="substring-after(.,'&lt;/span&gt;')"/>
    </xsl:template>

    >
    > and putting &lt; gives a stack overflow exception as it seems to make
    > the proccessor recurse continually.


    this template doesn't recurse; check elsewhere how it is invoked

    to make it run alone, change the template that matches the root:

    <xsl:template match='/'>
    <xsl:apply-templates select="//end_time"/>
    </xsl:template>

    after the last <xsl:value-of>, you also might find useful to add \n :
    <xsl:text>
    </xsl:text>

    --
    Cordialement,

    ///
    (. .)
    --------ooO--(_)--Ooo--------
    | Philippe Poulard |
    -----------------------------
    http://reflex.gforge.inria.fr/
    Have the RefleX !
     
    Philippe Poulard, Jun 17, 2009
    #14
  15. Mayeul Guest

    wrote:
    > So, basically, i want this:
    >
    > [snip]
    >
    > Yes it's in a CDATA tag but that doesn't seem to change anything at
    > all.
    >


    Actually, it changes just about everything. By definition, there are no
    elements in a CDATA tag. XSLT is mainly designed to operate with XPath
    rules, not with raw text.

    --
    Mayeul
     
    Mayeul, Jun 17, 2009
    #15
  16. As others have said, that isn't "a tag in text" -- it's text which
    happens to look like a tag. Your only option is string manipulation.
     
    Joe Kesselman, Jun 18, 2009
    #16
  17. Note too that putting "tags" in text is generally Bad Practice unless
    you really want the visible representation of a tag rather than an
    actual element. If you're writing an XML/HTML tutorial, what you're
    doing may make sense. If that isn't what you're doing, this is probably
    not saying what you want it to say.
     
    Joe Kesselman, Jun 18, 2009
    #17
  18. Guest

    Dunno where you guys work but i'd love the choice of what data i
    get :)

    I'm sorry to say this, but again, using string manipulation just isn't
    working.
    Here's my code:
    <xsl:template name="removeSpan">
    <xsl:param name="variable"/>
    <xsl:if test="contains($variable, 'span')"><xsl:text>value:</
    xsl:text></xsl:if>
    <xsl:value-of select="substring-before($variable, 'span')"/>
    <xsl:value-of select="substring-after($variable, 'hit&quot;')"/>
    <xsl:text>jim</xsl:text><xsl:value-of select="$variable"/>
    </xsl:template>

    Here's the output:
    jim01:
    <span class="hit">
    22
    </span>
    :45

    As you can see it doesn't even like "span" ?! (i of course tried this
    with &lt; and even < first)

    Anyone see why this is going wrong?
     
    , Jun 18, 2009
    #18
  19. Guest

    i can however pull back:
    01:<span class="hit">

    if i try and do:
    substring-before($variable, "22").
     
    , Jun 18, 2009
    #19
  20. Guest

    On Jun 18, 10:29 am, "" <>
    wrote:
    > i can however pull back:
    > 01:<span class="hit">
    >
    > if i try and do:
    > substring-before($variable, "22").


    Ahem, yes, found the problem. The output was going through a proccess
    i was unaware of, converting [mkup][mkup] tags to <span class="hit"></
    span>.

    So, yeah er, problem solved. Reason i couldn't just manipulate the
    string to get rid of <span> was that it wasn't there.

    Yes, i deserve your scorn (and pity).

    Thats a day i'll never get back again :(

    Thanks for your help though i guess.
     
    , Jun 18, 2009
    #20
    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. shruds
    Replies:
    1
    Views:
    834
    John C. Bollinger
    Jan 27, 2006
  2. Replies:
    18
    Views:
    2,762
    Joseph Kesselman
    Oct 4, 2006
  3. M Wells
    Replies:
    0
    Views:
    141
    M Wells
    Oct 6, 2004
  4. jwcarlton

    Removing tag + closing tag

    jwcarlton, Sep 21, 2010, in forum: Perl Misc
    Replies:
    12
    Views:
    179
  5. visu
    Replies:
    4
    Views:
    302
Loading...

Share This Page