How to change value of sibling attribute
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" />
</Asse开发者_如何学编程t>
</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
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>
精彩评论