2009-11-05 11 views
1

J'ai un document XML généré à partir d'une application externe, mais cette application n'a pas accès à certaines informations de fichier, à savoir une somme de contrôle de fichier. L'élément est inclus dans le ouptut, mais la valeur est vide. J'ai besoin de modifier le XML via un XSL pour inclure la somme de contrôle, mais j'ai du mal à créer un XSL pour le faire. Dans l'exemple ci-dessous, il y a 3 éléments ADI/Asset/Asset, chacun représentant un fichier individuel (le film, un aperçu et un poster). La somme de contrôle est transmise via un XsltArgumentList pour chaque fichier (en utilisant XslCompiledTransform pour faire les transformations). Je peux créer un modèle qui correspond à l'élément d'élément droit, mais qui doit ensuite modifier son élément frère.Comment changer la valeur d'un attribut frère

Il n'y aura plus qu'un seul actif avec un élément, ou toute autre valeur pour la valeur.

<?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> 

Nécessité de se rendre à:

<?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> 

Merci pour toute aide.

Brian

+0

Est-ce que vous voulez dire avez x 'MetaData' éléments par fichier? Combien de paramètres a la feuille de style, alors? – Tomalak

+0

Il y aura un nombre d'actifs par ADI/Asset, mais seulement 1 MetaData par ADI/Asset/Asset. En pratique, il n'y aura que le 3 (film, preview, poster). Actuellement, il n'y a que 2 paramètres, movie_checksum et preview_checksum. – Brian

+0

@Brian: J'ai amélioré ma réponse. C'est plus court et moins redondant maintenant. – Tomalak

Répondre

3

Cela peut se faire avec une transformation d'identité modifiée:

<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> 
+0

A travaillé parfaitement. Seulement changé '' à '' car les noms de fichiers seront différents pour chaque fichier généré. Merci! – Brian

+0

J'ai changé ce détail, et j'ai aussi légèrement déflaté le second modèle. – Tomalak

Questions connexes