使用XSLT将RSS pubDate转换为mySQL时间戳格式

时间:2016-02-12 10:42:23

标签: mysql xslt rss

我有一个小工具可以剥离并重新排列iTunes格式的RSS源,并将其转换为简单的XML文件。

然后我将清理后的XML导入mySQL,以便稍后再做。

我需要能够将feed中的pubDate转换为mySQL时间戳,以便我可以将其正确导入到我的表中的TIMESTAMP字段中。

我遇到了一些问题。

我当前的XSL文件在日期上做得很整齐,但我根本不需要这个。

我只希望<pubDate>节点在内部拥有正确的mySQL友好时间戳。

我还没有找到能满足我需要的任何东西。有什么指针吗?

这是我的XSLT文件......

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:atom="http://www.w3.org/2005/Atom" 
    xmlns:cc="http://web.resource.org/cc/"
    xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
    xmlns:libsyn="http://libsyn.com/rss-extension" 
    xmlns:media="http://search.yahoo.com/mrss/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    exclude-result-prefixes="atom cc itunes libsyn media rdf">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <data>
            <entries>
                <xsl:apply-templates select="rss/channel/item"></xsl:apply-templates>
            </entries>
        </data>
    </xsl:template>

    <xsl:template match="item">
        <entry>
            <title><xsl:value-of select="title"/></title>
            <link><xsl:value-of select="link"/></link>
            <description><xsl:value-of select="description" disable-output-escaping="yes"/></description>
            <subtitle><xsl:value-of select="itunes:subtitle"/></subtitle>
            <pubDate><xsl:value-of select="pubDate"/></pubDate>
            <xsl:apply-templates select="pubDate"/>
            <explicit><xsl:value-of select="itunes:explicit"/></explicit>
            <podcastImage><xsl:value-of select="itunes:image/@href"/></podcastImage>
            <podcastURL><xsl:value-of select="enclosure/@url"/></podcastURL>
            <podcastLength><xsl:value-of select="enclosure/@length"/></podcastLength>
            <podcastDuration><xsl:value-of select="itunes:duration"/></podcastDuration>
        </entry>
    </xsl:template>

    <xsl:template match="pubDate">
        <date>
            <xsl:attribute name="time"><xsl:value-of select="substring(text(),18,5)"/></xsl:attribute>
            <xsl:call-template name="format-from-rfc-to-iso">
                <xsl:with-param name="rfc-date" select="text()"/>
            </xsl:call-template>
        </date>
    </xsl:template>

    <xsl:template name="format-from-rfc-to-iso">
        <xsl:param name="rfc-date"/>
        <xsl:param name="day-with-zero" select="format-number(substring(substring($rfc-date,6,11),1,2),'00')"/>
        <xsl:param name="month-with-zero">
            <xsl:if test="contains($rfc-date,'Jan')">01</xsl:if>
            <xsl:if test="contains($rfc-date,'Feb')">02</xsl:if>
            <xsl:if test="contains($rfc-date,'Mar')">03</xsl:if>
            <xsl:if test="contains($rfc-date,'Apr')">04</xsl:if>
            <xsl:if test="contains($rfc-date,'May')">05</xsl:if>
            <xsl:if test="contains($rfc-date,'Jun')">06</xsl:if>
            <xsl:if test="contains($rfc-date,'Jul')">07</xsl:if>
            <xsl:if test="contains($rfc-date,'Aug')">08</xsl:if>
            <xsl:if test="contains($rfc-date,'Sep')">09</xsl:if>
            <xsl:if test="contains($rfc-date,'Oct')">10</xsl:if>
            <xsl:if test="contains($rfc-date,'Nov')">11</xsl:if>
            <xsl:if test="contains($rfc-date,'Dec')">12</xsl:if>
        </xsl:param>
        <xsl:param name="year-full" select="format-number(substring(substring($rfc-date,6,11),7,5),'####')"/>
        <xsl:param name="rfc-date-to-iso" select="concat($year-full,'-',$month-with-zero,'-',$day-with-zero)"/>

        <xsl:value-of select="$rfc-date-to-iso"/>

    </xsl:template>

</xsl:stylesheet>

当前日期/时间从rss Feed看起来像这样:

<pubDate>Sun, 07 Feb 2016 00:00:56 -0500</pubDate>

我喜欢这样显示,所以它可以插入mySQL:

<pubDate>2016-02-07 00:00:56</pubDate>

我使用PHP来处理它。

$xml = new DOMDocument;
$xml->load('podbean.xml');

$xsl = new DOMDocument;
$xsl->load('podbean.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // attach the xsl rules

$proc->transformToXML($xml);

$proc->transformToURI($xml,'itunes.xml');

西蒙

1 个答案:

答案 0 :(得分:0)

使用支持EXSLT str:tokenize()功能的处理器(如libxslt所做的那样),你可以这样做:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- ... -->

<xsl:template match="item">
    <entry>
        <!-- ... -->
        <pubDate>
            <xsl:variable name="date-tokens" select="str:tokenize(pubDate, ' ' )" />
            <!-- year -->
            <xsl:value-of select="$date-tokens[4]" />
            <xsl:text>-</xsl:text>
            <!-- month -->
            <xsl:variable name="mmm" select="$date-tokens[3]" />
            <xsl:variable name="m" select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', $mmm)) div 3 + 1" />
            <xsl:value-of select="format-number($m, '00')" />
            <xsl:text>-</xsl:text>  
            <!-- day -->
            <xsl:value-of select="format-number($date-tokens[2], '00')" />
            <xsl:text> </xsl:text>
            <!-- time -->
            <xsl:value-of select="$date-tokens[5]" />
        </pubDate>
        <!-- ... -->
    </entry>
</xsl:template>

</xsl:stylesheet>