Q:

XSLT nested lookup

New to XSLT, but have been learning a lot from posts here.  However, I'm stuck on one problem.
I am using XSLT to create a report for a device installation.  The input XML looks like this:
<DeviceTypes>
  <DeviceInfo Model="51473">
    <Channels>
      <ChannelInfo ChannelId="1" IsImplemented="false" SampRateHardware="448" />
      <ChannelInfo ChannelId="2" IsImplemented="true" SampRateHardware="224" />
    </Channels>
  </DeviceInfo>
  <DeviceInfo Model="51474">
    <Channels>
      <ChannelInfo ChannelId="1" IsImplemented="true" SampRateHardware="448" />
      <ChannelInfo ChannelId="2" IsImplemented="true" SampRateHardware="224" />
    </Channels>
  </DeviceInfo>
</DeviceTypes>
<Installation>
  <InstalledDevice Serial="597657" Model="51473">
    <Channels>
       <InstalledChannel ChannelId="1" Name="foo" />
       <InstalledChannel ChannelId="2" Name="bar" />
    </Channels> 
  </InstalledDevice>
</Installation>

I want to only process the InstallChannel node if the corresponding ChannelInfo has an "IsImplemented" set to true.  By "corresponding" I mean I am looking for the ChannelInfo with the same ChannelId and the same Model under the parent node.  Note that channels with the same ChannelId may have different IsImplemented values depending on what device they are under.
I've been using  and the key() function to successfully lookup, but this nested lookup has me stumped.
Thanks,
-Mat

A:

I believe that using the templates makes for better readability/extendability:  The key is using the variable to be able to reference both the Model and the ChannelId for the ChannelInfo node in the xpath for the InstalledChannel, so start with the InstalledDevice, and work your way down the heirarchy
<xsl:apply-templates select="//InstalledDevice"/>

<xsl:template match="//InstalledDevice">
   <xsl:variable name="model">
       <xsl:value-of select="@Model"/>
   </xsl:variable>

   <xsl:for-each select="Channels/InstalledChannel">
      <xsl:variable name="channelId">
         <xsl:value-of select="@ChannelId"/>
      </xsl:variable>

      <xsl:if test="//DeviceInfo[@Model=$model]/Channels/ChannelInfo[@ChannelId=$channelId and @IsImplemented='true']">
         Processing Goes Here
      </xsl:if>
   </xsl:for-each>
</xsl:template>   

So that we can preserve context of our model variable,  I moved the InstalledChannel processing into the same template, and added the for-each.  That way each InstalledChannel instance can be examined individually for whether it needs to be processed, and handled accordingly.  

