2

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 :)

0

2 Answers 2

6

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>
Sign up to request clarification or add additional context in comments.

Comments

1

You're pretty close. Global parameters passed to the stylesheet should be declared at the outer level (moved to be following-sibling of the output element). The HLS format matching might as well be done directly in the template [@format='HLS']. Also you were missing an end-element marker on the value-of. Finally, you cannot change attributes of a matched element directly; hence the copy element below, emitting the matched element with existing attributes + updated format:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="someVariable"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="media/version[@format='HLS']">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="rel_path">
                <xsl:value-of select="concat(@format,$someVariable)"/>
            </xsl:attribute>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.