replaceing a href in RSS link with xsl regex

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • coflo
    New Member
    • Aug 2008
    • 9

    replaceing a href in RSS link with xsl regex

    Hello I would like to replace an a href link that is provided in the RSS below with my own link. The link that I am looking to replace is defined in the <description> tag within the RSS. Im guessing I need to use some sort of function in combination with regex.

    I am able to create a regex to find and replace the a href link very easily; however, using regex in combination with a find and replace in XSL i am extremly novice.

    I am wanting to replace the <description> a href:
    Code:
    a href='http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show'
    With this a href:
    Code:
    a href='javascript:void(kyteplayer.setURI('{$URIVal}'))'
    XML snippet:
    Code:
    <item>
    <title>New Show: Live Mobile Show</title>
    <link>http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show</link>
    <guid>http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show</guid>
    <description>&lt;a href='http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show'&gt;&lt;img src='http://media08.kyte.tv/store/005/08/crr/0808/02/23/689407-0-47639mobile_689407_120_90-tom-5000.jpg?aid=21808&amp;h=44fade2ef70a4df7e890f5f77c87f5d9' title='Live Mobile Show' width='120' height='90' alt='Live Mobile Show' border='0'/&gt;&lt;/a&gt;&lt;br&gt;produced by tenofquad.</description>
    
    <pubDate>Sat, 02 Aug 2008 23:18:20 +0000</pubDate>
    <media:content url="http://www.kyte.tv/flash.swf?appKey=MarbachViewerEmbedded&amp;uri=channels/39174/185592&amp;layoutMode=default" fileSize="30" type="application/x-shockwave-flash" height="425" width="425" duration="1"/>
    <enclosure url="http://www.kyte.tv/flash.swf?appKey=MarbachViewerEmbedded&amp;uri=channels/39174/185592&amp;layoutMode=default" length="30" type="application/x-shockwave-flash"/>
    </item>
    My XSL snippet:
    Code:
         <xsl:template match="item">     
    
            <xsl:variable name="item_link" select="link"/>
    
            <xsl:variable name="item_enclosure" select="enclosure/@url"/>
    
            <xsl:variable name="item_title" select="description"/>
    
            <xsl:variable name="item_media" select="media"/>
    
           
          <xsl:variable name="afterURI">
    
          <xsl:value-of select = "substring-after($item_enclosure, '&amp;uri=')" />
    
          </xsl:variable> 
    
                 <xsl:variable name="URIVal">
    
                  <xsl:choose>
    
                      <xsl:when test="contains($afterURI, '&amp;')">
     
                         <xsl:value-of select="substring-before($afterURI, '&amp;')"/>
    
                      </xsl:when>
    
                      <xsl:otherwise>
    
                        <xsl:value-of select="$afterURI"/>
    
                      </xsl:otherwise>
    
                   </xsl:choose>
    
                </xsl:variable>      
    
            <div class="subHead" style="width:500px;">
              <a href="javascript:void(kyteplayer.setURI('{$URIVal}'))"><xsl:value-of select="title" disable-output-escaping="yes"/></a></div>
    
              <div style="width:500px;">
    
           <xsl:value-of select="description" disable-output-escaping="yes"/><br/></div>
    
           
           (<xsl:value-of select="pubDate"/>)<br/> <hr/>
    
           </xsl:template>
    Please any help would be great!
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    Maybe I've misunderstood you... you want to replace the href (ok), but what should the output be? (rss again or html)

    for a simple replace I'd try
    [CODE=xsl]<xsl:element name="a">
    <xsl:attribut e name="href">
    <xsl:text>javas cript:void(kyte player.setURI(' {</xsl:text>
    <xsl:value-of select="child:: a/attribute::href "/>
    <xsl:text>} '))</xsl:text>
    </xsl:attribute>
    <xsl:value-of select="title" disable-output-escaping="yes"/>
    </xsl:element>
    // or shorter
    &amp;lt;a href="javascrip t:void(kyteplay er.setURI('{<xs l:value-of select="child:: a/attribute::href "/>} '))"&amp;gt;
    <xsl:value-of select="title" disable-output-escaping="yes"/>
    &amp;lt;/a&amp;gt;[/CODE]
    for replacing the old rss with the new rss you might to have a look here: XSL replacing …

    Comment

    • coflo
      New Member
      • Aug 2008
      • 9

      #3
      Ahhh sorry, IT SHOULD OUTPUT HTML as with the rest of my XSL.


      Also I am not trying to replace the href in <TITLE> but in <DESCRIPTION>

      to replace the href in the title with the variable i already have that working, although this is another great solution.

      Rather i am trying to replace the href in the <DESCRIPTION> with the same virable.

      It may be an easier approach since I can already assign the link with the variable in it to just strip out the img src of the <DESCRIPTION> and wrap it with the correct href?

      I hope this makes sense!?!?!

      Comment

      • Dormilich
        Recognized Expert Expert
        • Aug 2008
        • 8694

        #4
        Originally posted by coflo
        Also I am not trying to replace the href in <TITLE> but in <DESCRIPTION>
        sorry, but I don't get the point here... as far as I can see there's no href inside <title>.
        Originally posted by coflo
        Rather i am trying to replace the href in the <DESCRIPTION> with the same virable.
        but since you want to output html, maybe "replace" is not the best description (I have to admit it confuses me a little). Furthermore if you want the img as link content you may use <xsl:copy> (and of course feel free to tweak the xpath as you need it)
        just for clarity... you want to use the uri from <enclosure> and the img of <description> ? the thing to take care of is that you use the right xpath expressions (for the uri you have this set up and the img you can access with "item/description/a/img", just put these two in your template and you've got it)

        Comment

        • coflo
          New Member
          • Aug 2008
          • 9

          #5
          Interesting, that would make the most sense, sorry if I have been confusing - its because i wasn't quit sure of the correct way to go about this... by setting that xpath it doesn't seem to retrieve the image - i actually do not get anything an error or any data.

          Perhaps an actual example of how you would implement it in my template would help cause thus far it seems to be nothing. I tried google-ing to see if I could figure out how to grab that xpath in <description> but nothing concrete comes up.

          Comment

          • Dormilich
            Recognized Expert Expert
            • Aug 2008
            • 8694

            #6
            ok, let's assume it is RSS 2.0
            the xml snippet (just to have it at hand)
            [code=xml]<item>
            <title>New Show: Live Mobile Show</title>
            <link>http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show</link>
            <guid>http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show</guid>
            <description>
            <a href='http://www.kyte.tv/ch/39174-flocam/185592-live-mobile-show'>
            <img src='_img_sourc e_' title='Live Mobile Show' width='120' height='90' alt='Live Mobile Show' border='0'/>
            </a>
            <br>
            produced by tenofquad.
            </description>
            <pubDate>Sat, 02 Aug 2008 23:18:20 +0000</pubDate>
            <media:conten t url="_same_as_e nclosure_url_" fileSize="30" type="applicati on/x-shockwave-flash" height="425" width="425" duration="1"/>
            <enclosure url="http://www.kyte.tv/flash.swf?appKe y=MarbachViewer Embedded&uri=channels/39174/185592&layoutMode=def ault" length="30" type="applicati on/x-shockwave-flash"/>
            </item>[/code]
            the html snippet we want to create
            [code=html]<div class="subHead" > // I dropped the style here because you can define that in CSS
            <a href="javascrip t:void(kyteplay er.setURI('channels/39174/185592'))">
            <img src='_img_sourc e_' title='Live Mobile Show' width='120' height='90' alt='Live Mobile Show'> // you should define img border in CSS too
            </a>
            </div>[/code]
            note: it is not absolutely clear to me what you want to put inside the link, for now I assume the image.

            you see the content marked bold? (I call this content mapping) we now have to find a xsl way to transform one towards the other.
            Essentially I do it like this: replace the content we want to have by an appropriate xsl element along with its xpath expression. The difficult part here is to get the XPath right.

            step 1 - get the <item> element (as it is the nearest ancestor to both targets (the image and the href) so we can use it as base node)
            step 2 - find an XPath expression that matches our targets (we start from <item> now)
            step 3 - build the html around that (the html markup not in bold)
            [code=xsl]<xsl:template match="//item"> <!-- step 1 -->
            <!-- define the uri value we need -->
            <xsl:variable name="URIVal"> <!-- step 2 -->
            <xsl:choose>
            <xsl:when test="contains( enclosure/@url, '&')">
            <xsl:value-of select="substri ng-before(enclosur e/@urlI, '&')"/>
            </xsl:when>
            <xsl:otherwis e>
            <xsl:value-of select="enclosu re/@url"/>
            </xsl:otherwise>
            </xsl:choose>
            </xsl:variable>
            <!-- start defining the html -->
            <div class="subHead" > <!-- step 3 -->
            <a href="javascrip t:void(kyteplay er.setURI('{$URIVal}'))">
            <xsl:copy-of select="child:: description/descendant::img "> <!-- step 2 -->
            </a>
            </div>
            </xsl:template>[/code]
            it is relatively easy to get the image, but for the uri (or rather its part we want) it is not that easy, but you have managed a way to retrieve it (congratulaions !).

            you see how we have mapped the content from the xml to the html (or vice versa)?

            I hope this will help you

            PS: XPath axes provide a comfortable way to move inside the DOM tree

            Comment

            • Dormilich
              Recognized Expert Expert
              • Aug 2008
              • 8694

              #7
              Originally posted by coflo
              by setting that xpath it doesn't seem to retrieve the image - i actually do not get anything an error or any data.
              well it was rather a sketch than a correct XPath. I meant to give you an idea how to get the image. You can use even something like select="descend ant::img" (assuming there is only one image in the item)

              Comment

              • coflo
                New Member
                • Aug 2008
                • 9

                #8
                Originally posted by Dormilich
                well it was rather a sketch than a correct XPath. I meant to give you an idea how to get the image. You can use even something like select="descend ant::img" (assuming there is only one image in the item)
                Ya i understand the idea, but that is why i posted here.........i have no idea how to select it.....it took me forever, with alot of help......to get the uri and turn it into a variable....i am seeing a more clear way of selecting the image but still can't get it to seem to work.

                Comment

                • Dormilich
                  Recognized Expert Expert
                  • Aug 2008
                  • 8694

                  #9
                  replacing a href in RSS link with xsl regex

                  Originally posted by coflo
                  i am seeing a more clear way of selecting the image but still can't get it to seem to work.
                  after trying by myself I had no trouble getting the image. (see attached files)
                  note: there was no visible output, but the code proves the correctness.
                  Attached Files

                  Comment

                  • coflo
                    New Member
                    • Aug 2008
                    • 9

                    #10
                    Originally posted by Dormilich
                    after trying by myself I had no trouble getting the image. (see attached files)
                    note: there was no visible output, but the code proves the correctness.
                    Two things that are apparant when using this code.
                    1. It gives the error cannot 'xsl:param' cannot be a child of the 'xsl:template' element.

                    2. My RSS feed does not look like the feed that you have created. The <description> is not written the way you have displayed it other wise this would have been an easy task. look at the actual RSS feed to see the example: http://www.kyte.tv/channels/rss.html?uri=ch annels/39174

                    As you can see its not as clear cut defining the im src as given in the example you have sent to me, thus why this code does not work. This is why i thought it would be wise to use some sort of regex to pick out the img src, i just can't figure it out!

                    Comment

                    • Dormilich
                      Recognized Expert Expert
                      • Aug 2008
                      • 8694

                      #11
                      some notes

                      1. this is not according to the specification of the W3C (chapter 11 and 2.2). I only switched to xsl:param for tryout, xsl:variable should work as well.

                      2. well, you never mentioned the link would be escaped. but roughly, I'd do something like that of the $urival.

                      regards

                      Comment

                      • Dormilich
                        Recognized Expert Expert
                        • Aug 2008
                        • 8694

                        #12
                        I didn't go for a variable, eventually. But I got this working (without a regex, regex is not part of xslt 1.0)
                        Code:
                        <xsl:template match="//item">
                            <xsl:param name="URIVal">
                         ...
                              </xsl:param>
                              
                        <div class="subHead">
                            <a>
                                <xsl:attribute name="href">javascript:void(kyteplayer.setURI('<xsl:value-of select="$URIVal"/>'))</xsl:attribute>
                                <xsl:element name="img">
                                    <xsl:attribute name="src">
                                        <xsl:call-template name="getAttr">
                                            <xsl:with-param name="attrName">src</xsl:with-param>
                                        </xsl:call-template>
                                    </xsl:attribute>
                        // define the other attributes accordingly, maybe there is a kind of foreach/array possible
                                </xsl:element>
                            </a>
                        </div>
                        </xsl:template>
                        
                        <xsl:template name="getAttr">
                            <xsl:param name="attrName"/>
                        // make sure to match the attribute not an url variable
                            <xsl:param name="pattern">
                                <xsl:text> </xsl:text>
                                <xsl:value-of select="$attrName"/>
                                <xsl:text>='</xsl:text>
                            </xsl:param>
                        // extract string from $pattern up to the next space
                            <xsl:param name="help" select="substring-before(substring-after(description, $pattern), ' ')"/>
                        // remove ' from string (unfortunately replace doesn't work because ' is a string delimiter) and print result
                            <xsl:value-of select="substring($help, 1, string-length($help)-1)"/>
                        </xsl:template>
                        this sure is a tough task.

                        regards

                        Comment

                        Working...