RSS の URI から OPML を作る XSLT。
各エントリごとに document 関数でネットの向こうへ RSS を取りに行くので、<?xml-stylesheet?> で使うのは激しく非推奨。
一度 XSLT プロセッサに通して静的な OPML にするが吉。
生成する OPML は 2.0。
対応フィードは RSS 1.0 と RSS 2.0。Atom には対応してません。
<?xml version="1.0" encoding="UTF-16" standalone="yes" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:opml="http://opml.org/spec2"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rss="http://purl.org/rss/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
exclude-result-prefixes="rdf rss dc">
<xsl:output method="xml" version="1.0" encoding="UTF-16"
omit-xml-declaration="no" standalone="yes" indent="yes" media-type="application/opml+xml"/>
<xsl:template match="/opml:opml">
<xsl:copy>
<xsl:attribute name="version">2.0</xsl:attribute>
<xsl:attribute name="xml:lang">ja-JP</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="//opml:outline[@type='rss']">
<xsl:copy>
<xsl:attribute name="type">rss</xsl:attribute>
<xsl:attribute name="xmlUrl"><xsl:value-of select="@xmlUrl"/></xsl:attribute>
<xsl:apply-templates select="document(@xmlUrl)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/rss[@version='2.0']/channel">
<xsl:attribute name="title"><xsl:value-of select="title"/></xsl:attribute>
<xsl:attribute name="text"><xsl:value-of select="title"/></xsl:attribute>
<xsl:attribute name="htmlUrl"><xsl:value-of select="link"/></xsl:attribute>
<xsl:attribute name="description"><xsl:value-of select="description"/></xsl:attribute>
<xsl:attribute name="version">RSS</xsl:attribute>
<xsl:attribute name="language"><xsl:value-of select="language"/></xsl:attribute>
</xsl:template>
<xsl:template match="/rdf:RDF/rss:channel">
<xsl:attribute name="title"><xsl:value-of select="rss:title"/></xsl:attribute>
<xsl:attribute name="text"><xsl:value-of select="rss:title"/></xsl:attribute>
<xsl:attribute name="htmlUrl"><xsl:value-of select="rss:link"/></xsl:attribute>
<xsl:attribute name="description"><xsl:value-of select="rss:description"/></xsl:attribute>
<xsl:attribute name="version">RSS1</xsl:attribute>
<xsl:attribute name="language"><xsl:value-of select="dc:language"/></xsl:attribute>
</xsl:template>
<xsl:template match="//opml:*[not (name()='outline' and @type = 'rss' )]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="text() | @*"/>
</xsl:stylesheet>
入力ファイルは以下のような感じで。
type=rss の outline 要素に、xmlUrl から取ってきた情報を補充します。
type=rss でない outline 要素はそのまま書き出します。
<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<opml version="2.0" xmlns="http://opml.org/spec2" xml:lang="ja-JP">
<head/>
<body>
<outline type="rss" xmlUrl=""/>
</body>
</opml>
おまけでデバッグ用に作ったのが、type=rss の outline 要素から type と xmlUrl 以外の属性を除去する XSLT。
<?xml version="1.0" encoding="utf-16" standalone="yes" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:opml="http://opml.org/spec2"
xmlns="http://opml.org/spec2">
<xsl:output method="xml" version="1.0" encoding="UTF-16"
omit-xml-declaration="no" standalone="yes" indent="yes" media-type="application/opml+xml"/>
<xsl:template match="//opml:outline[@type='rss']">
<xsl:copy>
<xsl:attribute name="type">rss</xsl:attribute>
<xsl:attribute name="xmlUrl"><xsl:value-of select="@xmlUrl"/></xsl:attribute>
</xsl:copy>
</xsl:template>
<xsl:template match="//opml:*[not (name()='outline' and @type = 'rss' )]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>