tags:

views:

42

answers:

1

Is it possible to do a find and replace to the attributes of a xml element? I want to change the directory that is being pointed to by a href:

From:

<image href="./views/screenshots/page1.png">

to

<image href="screenshots/page1.png"> 

And from:

<image href="./screenshots/page2.png">

to

<image href="screenshots/page2.png">

So by getting rid of all "./" that belong to the href of all image tags, but only the image tags. And furthermore, get rid of first folder if it is not named "screenshots". Is there a simple way to do this in one go?

+2  A: 

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="image/@href[starts-with(.,'./screenshots/')]">
  <xsl:attribute name="href">
   <xsl:value-of select="substring(.,3)"/>
  </xsl:attribute>
 </xsl:template>

  <xsl:template match=
   "image/@href
     [starts-with(.,'./')
     and not(starts-with(substring(.,3), 'screenshots/'))
     ]">
  <xsl:attribute name="href">
   <xsl:value-of select="substring-after(substring(.,3),'/')"/>
  </xsl:attribute>
 </xsl:template>


 <xsl:template priority="10"
      match="image/@href[starts-with(.,'./views/')]">
  <xsl:attribute name="href">
   <xsl:value-of select="substring(.,9)"/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

   <t>
    <image href="./views/screenshots/page1.png"/>
    <image href="./screenshots/page2.png"/>
    <load href="./xxx.yyy"/>
    <image href="ZZZ/screenshots/page1.png"/>
   </t>

produces the wanted result:

<t>
    <image href="screenshots/page1.png"/>
    <image href="screenshots/page2.png"/>
    <load href="./xxx.yyy"/>
    <image href="ZZZ/screenshots/page1.png"/>
</t>

Do note:

  1. The use and overriding of the identity rule. This is the most fundamental and most powerful XSLT design pattern.

  2. Only href attributes of image elements are modified.

  3. Only href attributes that start with the string "./" or the string "./{something-different-than-screenshots}/" are processed in a special way (by separate templates).

  4. All other nodes are only processed by the identity template.

  5. This is a pure "push style" solution.

Dimitre Novatchev
@Dimitre: +1 Excellent answer.
Alejandro
Yes this is close to what I need, but how do remove the "./views/" when it crops up, but only when folder is "views"?
Ace
@Ace: You need to rephrase your question. At present it is asking for "getting rid of all "./" that belong to the href of all image tags, but only the image tags". Could you specify the new requirement clearly?
Dimitre Novatchev
Added description that preceding folder sometimes need to be reomved
Ace
@Ace: There is contradiction in your new text: "subFolder" is not "screenshots" but you show it not-removed in the results. Please, correct.
Dimitre Novatchev
@Ace: I edited your question so that now there is no mismatch between the requirements and the stated wanted result. Please, verify this is correct. I also edited my answer and it now contains a solution that solves exactly the newly-formulated problem. Is everything OK now?
Dimitre Novatchev
Sorry for all the confusion, even in the mis-edits. The question has been fixed again, so it should be perfect now. Thanks for you patience.
Ace
@Ace: No problem. I updated my answer accordingly.
Dimitre Novatchev
Yes! The solutions works. Just out of curiosity (since this might come up in the future). I noticed that you solution checks for 'views', what if I want to remove any './' and all preceding folders up and until 'screenhots'?
Ace
@Ace: THere is still something undefined in your question. If you have: `./a/b/screenshots/c/screenshots/page1.png` -- what should be the result? When you definr this explicitly, it would be good to ask a new question.
Dimitre Novatchev
question reposted on "XSL: removing preceding folders on image path"
Ace