Replace xml attribute based on the other attribute value

xml, xslt

Solution

A shorter solution, using AVT (Attribute Value Templates):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:param name="psomeParam" select="'/xxx'"/>

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

 <xsl:template match="version[@format='HLS']">
  <version rel_path="{@rel_path}{$psomeParam}">
   <xsl:apply-templates select="@*[not(name()='rel_path')] | node()"/>
  </version>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<asset_detail>
    <asset id="1" show_type="Movies">
        <title><![CDATA[Movie]]></title>
        <media_list>
            <media id="11" title="" type="trailer">
                <version format="m3u8" rel_path="/Content/movie.m3u8"/>
                <version format="HLS" rel_path="/movies/movie.m3u8"/>
            </media>
        </media_list>
    </asset>
</asset_detail>

the wanted, correct result is produced:

<asset_detail>
   <asset id="1" show_type="Movies">
      <title>Movie</title>
      <media_list>
         <media id="11" title="" type="trailer">
            <version format="m3u8" rel_path="/Content/movie.m3u8"/>
            <version rel_path="/movies/movie.m3u8/xxx" format="HLS"/>
         </media>
      </media_list>
   </asset>
</asset_detail>

Problem

I'm new to XSLT, so I'll really appreciate any help. I've searched a lot on stackoverflow, tried to apply several approaches, but failed. I have an xml like this: ``` <?xml version="1.0" encoding="utf-8"?> <asset_detail> <asset id="1" show_type="Movies"> <title><![CDATA[Movie]]></title> <media_list> <media id="11" title="" type="trailer"> <version format="m3u8" rel_path="/Content/movie.m3u8"/> <version format="HLS" rel_path="/movies/movie.m3u8"/> </media> </media_list> </asset> </asset_detail> ``` I should copy the whole xml and: ``` if media_list/media/version/@format = '**HLS**' I need to replace **@rel_path** with value: **concat**(existing value of **@rel_path****,** **someVariable** (I'm passing to xsl as a <xsl:param>) ``` I think I have to use something like: ``` <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@*|node()"> <xsl:param name="someVariable"/> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="media/version"> <xsl:attribute name="rel_path"> <xsl:choose> <xsl:when test="./@format = HLS"> <xsl:value-of select="concat(rel_path,$someVariable)"> </xsl:when> </xsl:choose> </xsl:attribute> </xsl:template> </xsl:stylesheet> ``` I know it doesn't work :)

Original source