Search code examples
xmlxsltrdf

Apply two xslt transformation on the same file


I have this RSS I want to transform using XSLT:

<?xml version="1.0" encoding="utf-8" ?>
<rdf xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
 xmlns="http://purl.org/rss/1.0/">

  <channel rdf:about="http://www.example1.com">
    <title>atitle</title>
    <link>alink</link>
  </channel>

  <item rdf:about="http://www.example2.com">
    <title>atitle2</title>
    <link>alink2</link>
  </item>

  <item rdf:about="http://www.example3.com">
    <title>atitle3</title>
    <link>alink3</link>
  </item>

  <!--There's more to the file-->

</rdf>

I had to use this transformation

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

  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

to clear the attributes of the file so it would look like this

<?xml version="1.0" encoding="utf-8" ?>
<rdf>

  <channel>http://www.example1.com
    <title>atitle</title>
    <link>alink</link>
  </channel>

  <item>http://www.example2.com
    <title>atitle2</title>
    <link>alink2</link>
  </item>

  <item>http://www.example2.com
    <title>atitle3</title>
    <link>alink3</link>
  </item>

  <!--There's more to the file-->

</rdf>

My main goal is to simply make a list of items like this:

<items>
  <item title="atitle2" link="alink2">
  <item title="atitle3" link="alink3">
</items>

Do I have to make a second transformation, something like this?

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

  <xsl:template match="/rdf">
    <items>
      <xsl:for-each select="/item">
        <item>
          <xsl:attribute name="title">
            <xsl:value-of select="title"/>
          </xsl:attribute>
          <xsl:attribute name="link">
            <xsl:value-of select="link"/>
          </xsl:attribute>
        </item>
      </xsl:for-each>
    </items>
  </xsl:template>
</xsl:stylesheet>

Or is there a way to apply two transformations at the same time? Or do I have to apply them separately? Or maybe an easier way than the one I'm trying?


Solution

  • How about this single stylesheet:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://purl.org/rss/1.0/" exclude-result-prefixes="ns">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <items>
            <xsl:apply-templates select="//ns:item"/>
        </items>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="*" mode="child"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="*" mode="child">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    </xsl:stylesheet>