XIP aus RSS-Feed: Unterschied zwischen den Versionen

Aus SiteparkWiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „Mit folgendem Beispiel lässt sich ein RSS-Feed (Version 2.0) importieren. Die einzelnen Einträge werden als Resource-Artikel angelegt. Der Anchor der Resource-A…“)
 
 
(4 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 38: Zeile 38:
  
 
     <!--
 
     <!--
     int xip:hashCode(String s)
+
     xs:decimal xip:hashCode(String s)
 
     Erzeugt aus einer Zeichenkette einen Hash-Code
 
     Erzeugt aus einer Zeichenkette einen Hash-Code
 
     -->
 
     -->
Zeile 77: Zeile 77:
 
</source>
 
</source>
  
 +
Weiterhin wäre es denkbar, wenn das Datum in einer geeigneteren Form ausgegeben würde. Hierzu könnte ein Template mit folgender Funktion verwendet werden:
 +
<source lang="xml">
 +
<?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" encoding="UTF-8" indent="yes"/>
 +
 +
    <xsl:template match="/">
 +
        <xip>
 +
            <xsl:for-each select="/rss/channel/item">
 +
                <resource parent="rss.pool" name="{title}" anchor="rss.item.{position()}">
 +
                    <text name="sp_date">
 +
                        <xsl:variable name="d" select="pubDate"/>
 +
                        <xsl:call-template name="formatDate">
 +
                            <xsl:with-param name="date" select="$d" />
 +
                        </xsl:call-template>
 +
                    </text>
 +
                    <text name="sp_intro"><xsl:value-of select="description"/></text>
 +
                    <url name="sp_link"><xsl:value-of select="link"/></url>
 +
                    <binary name="sp_bild" url="{enclosure/@url}"/>
 +
                </resource>
 +
            </xsl:for-each>
 +
        </xip>
 +
    </xsl:template>
 +
 +
    <xsl:template name="formatDate">
 +
      <xsl:param name="date" /><!-- Tue, 09 Mar 2010 11:21:18 +0100 -->
 +
 +
      <xsl:variable name="dayString" select="substring-before($date, ',')" />
 +
      <xsl:variable name="tmp" select="substring-after($date, ' ')" /><!-- 09 Mar 2010 11:21:18 +0100 -->
 +
 +
      <xsl:variable name="day" select="substring-before($tmp, ' ')" />
 +
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- Mar 2010 11:21:18 +0100 -->
 +
 +
      <xsl:variable name="monthString" select="substring-before($tmp, ' ')" />
 +
      <xsl:variable name="month" select="substring(
 +
        substring-after(
 +
            'Jan=01;Feb=02;Mar=03;Apr=04;May=05;Jun=06;Jul=07;Aug=08;Sep=09;Oct=10;Nov=11;Dec=12',
 +
            $monthString),
 +
        2,
 +
        2)" /><!-- englich month strings -->
 +
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- 2010 11:21:18 +0100 -->
 +
 +
      <xsl:variable name="year" select="substring-before($tmp, ' ')" />
 +
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- 11:21:18 +0100 -->
 +
 +
      <xsl:variable name="hour" select="substring-before($tmp, ':')" />
 +
      <xsl:variable name="tmp" select="substring-after($tmp, ':')" /><!-- 21:18 +0100 -->
 +
 +
      <xsl:variable name="minute" select="substring-before($tmp, ':')" />
 +
      <xsl:variable name="tmp" select="substring-after($tmp, ':')" /><!-- 18 +0100 -->
 +
 +
      <xsl:variable name="second" select="substring-before($tmp, ' ')" />
 +
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- +0100 -->
 +
 +
      <xsl:variable name="timezone" select="$tmp" />
 +
 +
      <xsl:value-of select="concat($day, '.', $month, '.', $year, ' ', $hour, ':', $minute, ':', $second)" />
 +
    </xsl:template>
 +
 +
</xsl:stylesheet>
 +
</source>
 
<noinclude>
 
<noinclude>
[[Category:XIP]]
+
[[XIP mit XSLT]]
 
</noinclude>
 
</noinclude>

Aktuelle Version vom 9. April 2010, 15:30 Uhr

Mit folgendem Beispiel lässt sich ein RSS-Feed (Version 2.0) importieren. Die einzelnen Einträge werden als Resource-Artikel angelegt. Der Anchor der Resource-Artikel ergibt sich aus der Position innerhalb des RSS-Feed.

<?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" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <xip>
            <xsl:for-each select="/rss/channel/item">
                <resource parent="rss.channel.x" name="{title}" anchor="rss.channel.x.item.{position()}">
                    <text name="description"><xsl:value-of select="description"/></text>
                    <url name="link"><xsl:value-of select="link"/></url>
                    <binary name="enclosure" url="{enclosure/@url}"/>
                </resource>
            </xsl:for-each>
        </xip>
    </xsl:template>

</xsl:stylesheet>

Beim obigen Beispiel hat die Verwendung der Position des Items innerhalb des RSS-Feed als Anchor zur Folge, das ein bestimmter Resource-Artikel bei Änderung des RSS-Feeds immer andere Daten enthält. Dies ist nicht immer gewünscht. Um dieses Problem zu lösen muss ein Eindeutige Anchor vergeben werden. Im RSS-Feed gibt es das Element <guid>, mit dem der Eintrag eindeutig identifiziert werden kann. Oftmals ist dieser Wert eine URL. Der Wert kann nicht direkt als Anchor verwendet werden, da in einer URL Zeichen enthalten sind, die in einem Anchor nicht enthalten sein dürfen.

Im folgenden Beispiel wird dieses Problem gelöst, indem ein Hash-Wert des <guid>-Elementes erzeugt wird.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xip="http://ies.sitepark.com/xip"
            extension-element-prefixes="xip">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <!--
     xs:decimal xip:hashCode(String s)
     Erzeugt aus einer Zeichenkette einen Hash-Code
    -->
    <xsl:function name="xip:hashCode">
        <xsl:param name="s"/>
        <xsl:value-of select="xs:decimal(xs:double(xip:hashCode($s, 1, 0)))"/>
    </xsl:function>
    <xsl:function name="xip:hashCode">
        <xsl:param name="s"/>
        <xsl:param name="i"/>
        <xsl:param name="h"/>
        <xsl:variable name="code" select="string-to-codepoints(substring($s, $i, 1))"/>
        <xsl:variable name="len" select="string-length($s)"/>
        <xsl:choose>
            <xsl:when test="($i + 1) &lt;= $len">
                <xsl:value-of select="xip:hashCode($s, $i+1, $h*31 + $code)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$h*31 + $code"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>


    <xsl:template match="/">
        <xip>
            <xsl:for-each select="/rss/channel/item">
                <resource parent="rss.channel.spiegel" name="{title}" code="{string-to-codepoints(guid)}" anchor="rss.channel.spiegel.item.{xip:hashCode(guid)}">
                    <text name="description"><xsl:value-of select="description"/></text>
                    <url name="link"><xsl:value-of select="link"/></url>
                    <binary name="enclosure" url="{enclosure/@url}"/>
                </resource>
            </xsl:for-each>
        </xip>
    </xsl:template>

</xsl:stylesheet>

Weiterhin wäre es denkbar, wenn das Datum in einer geeigneteren Form ausgegeben würde. Hierzu könnte ein Template mit folgender Funktion verwendet werden:

<?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" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <xip>
            <xsl:for-each select="/rss/channel/item">
                <resource parent="rss.pool" name="{title}" anchor="rss.item.{position()}">
                    <text name="sp_date">
                        <xsl:variable name="d" select="pubDate"/>
                        <xsl:call-template name="formatDate">
                            <xsl:with-param name="date" select="$d" />
                        </xsl:call-template>
                    </text>
                    <text name="sp_intro"><xsl:value-of select="description"/></text>
                    <url name="sp_link"><xsl:value-of select="link"/></url>
                    <binary name="sp_bild" url="{enclosure/@url}"/>
                </resource>
            </xsl:for-each>
        </xip>
    </xsl:template>

    <xsl:template name="formatDate">
      <xsl:param name="date" /><!-- Tue, 09 Mar 2010 11:21:18 +0100 -->

      <xsl:variable name="dayString" select="substring-before($date, ',')" />
      <xsl:variable name="tmp" select="substring-after($date, ' ')" /><!-- 09 Mar 2010 11:21:18 +0100 -->

      <xsl:variable name="day" select="substring-before($tmp, ' ')" />
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- Mar 2010 11:21:18 +0100 -->

      <xsl:variable name="monthString" select="substring-before($tmp, ' ')" />
      <xsl:variable name="month" select="substring(
        substring-after(
            'Jan=01;Feb=02;Mar=03;Apr=04;May=05;Jun=06;Jul=07;Aug=08;Sep=09;Oct=10;Nov=11;Dec=12',
            $monthString),
        2,
        2)" /><!-- englich month strings -->
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- 2010 11:21:18 +0100 -->

      <xsl:variable name="year" select="substring-before($tmp, ' ')" />
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- 11:21:18 +0100 -->

      <xsl:variable name="hour" select="substring-before($tmp, ':')" />
      <xsl:variable name="tmp" select="substring-after($tmp, ':')" /><!-- 21:18 +0100 -->

      <xsl:variable name="minute" select="substring-before($tmp, ':')" />
      <xsl:variable name="tmp" select="substring-after($tmp, ':')" /><!-- 18 +0100 -->

      <xsl:variable name="second" select="substring-before($tmp, ' ')" />
      <xsl:variable name="tmp" select="substring-after($tmp, ' ')" /><!-- +0100 -->

      <xsl:variable name="timezone" select="$tmp" />

      <xsl:value-of select="concat($day, '.', $month, '.', $year, ' ', $hour, ':', $minute, ':', $second)" />
    </xsl:template>

</xsl:stylesheet>

XIP mit XSLT