tags:

views:

48

answers:

1

I have an XML document generated from an external application, but that application does not have access to some file information, namely a file checksum. The element is included in the ouptut, but the value is empty. I need to modify the XML via an XSL to include the checksum, but am having difficulty creating an XSL to do this.

In the example below, there are 3 ADI/Asset/Asset elements, each representing an individual file (the movie, a preview, and a poster). The checksum is passed in via an XsltArgumentList for each file (using XslCompiledTransform to do the transforms). I can create a template that matches to the right Asset element, but then need to modify it's sibling element.

There will only ever be 1 Asset with an element , or any other value for Value.

<?xml version="1.0" encoding="utf-8"?>
<ADI>
  <Asset>
    <MetaData>
      <App_Data App="SVOD" Name="Title" Value="The Shawshank Redemption" />
    </MetaData>
    <Asset>
      <MetaData>
        <App_Data App="SVOD" Name="Type" Value="movie" />
        <App_Data App="SVOD" Name="Content_FileSize" Value="" />
        <App_Data App="SVOD" Name="Content_Checksum" Value="9645154523" />
      </MetaData>
      <Content Value="movie.wmv" />
    </Asset>
    <Asset>
      <MetaData>
        <App_Data App="SVOD" Name="Type" Value="preview" />
        <App_Data App="SVOD" Name="Content_FileSize" Value="" />
        <App_Data App="SVOD" Name="Content_Checksum" Value="5481523" />
      </MetaData>
      <Content Value="preview.wmv" />
    </Asset>
    <Asset>
      <MetaData>
        <App_Data App="SVOD" Name="Type" Value="poster" />
        <App_Data App="SVOD" Name="Content_CheckSum" Value="edb10756c98a83b72d913fb49fef64d7" />
        <App_Data App="SVOD" Name="Content_FileSize" Value="230456" />
      </MetaData>
      <Content Value="poster.bmp" />
    </Asset>
  </Asset>
</ADI>

Need to get to:

<?xml version="1.0" encoding="utf-8"?>
<ADI>
  <Asset>
    <MetaData>
      <App_Data App="SVOD" Name="Title" Value="The Shawshank Redemption" />
    </MetaData>
    <Asset>
      <MetaData>
        <App_Data App="SVOD" Name="Type" Value="movie" />
        <App_Data App="SVOD" Name="Content_FileSize" Value="My checksum value here" />
        <App_Data App="SVOD" Name="Content_Checksum" Value="9645154523" />
      </MetaData>
      <Content Value="movie.wmv" />
    </Asset>
    <Asset>
      <MetaData>
        <App_Data App="SVOD" Name="Type" Value="preview" />
        <App_Data App="SVOD" Name="Content_FileSize" Value="" />
        <App_Data App="SVOD" Name="Content_Checksum" Value="5481523" />
      </MetaData>
      <Content Value="preview.wmv" />
    </Asset>
    <Asset>
      <MetaData>
        <App_Data App="SVOD" Name="Type" Value="poster" />
        <App_Data App="SVOD" Name="Content_CheckSum" Value="edb10756c98a83b72d913fb49fef64d7" />
        <App_Data App="SVOD" Name="Content_FileSize" Value="230456" />
      </MetaData>
      <Content Value="poster.bmp" />
    </Asset>
  </Asset>
</ADI>

Thanks for any help.

Brian

+2  A: 

This can be done with a modified identity transformation:

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:param name="movie_checksum" select="''" />
  <xsl:param name="preview_checksum" select="''" />

  <!-- the identity template copies everything verbatim -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <!-- this template specifically handles checksum values -->
  <xsl:template match="App_Data[@Name = 'Content_Checksum']/@Value">
    <xsl:copy>
      <xsl:variable name="type" select="../App_Data[@Name='Type']/@Value" />
      <xsl:choose>
        <xsl:when test="$type = 'movie'">
          <xsl:value-of select="$movie_checksum" />
        </xsl:when>
        <xsl:when test="$type = 'preview'">
          <xsl:value-of select="$preview_checksum" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="." />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Tomalak
Worked perfectly. Only changed `<xsl:variable name="type" select="../../Content/@Value" />` to `<xsl:variable name="type" select="../App_Data[@Name='Type']/@Value" />` as the filenames will be different for each generated file. Thanks!
Brian
I've changed this detail, and also deflated the second template a bit.
Tomalak