Sudhakar
Sudhakar

Reputation: 4873

Select and display information only from the matching tags using XSLT

I am a noob when it comes to XSLT. So please bear with me if this question hits the basic mark.

Here's a sample of the XML I consume

<?xml version="1.0"?>
  <Types>
    <channels>
      <name>
        <id>0</id>
      </name>
      <channel_1>
        <id>1</id>
      </channel_1>
      <channel_2>
        <id>2</id>
      </channel_2>
      <channel_3>
        <id>3</id>
      </channel_3>
      <soschannel_4>
        <id>3</id>
      </soschannel_4>
    </channels>
  </Types>

Expected result: (only allow XML elements which start with name 'channel_' in the 'channels' element)

<?xml version="1.0"?>
  <Types>
    <channels>
      <channel_1>
        <id>1</id>
      </channel_1>
      <channel_2>
        <id>2</id>
      </channel_2>
      <channel_3>
        <id>3</id>
      </channel_3>
    </channels>
  </Types>

Upvotes: 0

Views: 73

Answers (2)

Michael Kay
Michael Kay

Reputation: 163458

You want a stylesheet with two rules:

An identity rule

<xsl:template match="*">
  <xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>

and a special rule for channels:

<xsl:template match="channels">
  <xsl:copy>
    <xsl:apply-templates select="*[starts-with(name(), 'channel')]"/>
  </xsl:copy>
</xsl:template>

Upvotes: 2

Mads Hansen
Mads Hansen

Reputation: 66783

This can be achieved easily using a modified identity transform:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <!--identity template, copies all content as default behavior-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="channels">
        <!--copy the element-->
        <xsl:copy>
            <!--handle any attributes, comments, and processing-instructions 
                (not present in your example xml, but here for completeness) -->
            <xsl:apply-templates select="@* | 
                                        comment() | 
                                        processing-instruction()"/>
            <!--only process the child elements whos names start with 'channel_' 
                any others will be ignored-->
            <xsl:apply-templates 
                              select="*[starts-with(local-name(), 'channel_')]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 2

Related Questions