2

我对 xsl 还很陌生,正在尝试找到一种方法来隐藏或静音 wordpress rss 提要的 xml 中除了两个节点之外的所有节点,结构如下:

?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
    <title>Title</title>
    <atom:link href="http://www.alink.com" rel="self" type="application/rss+xml" />
    <link>http://www.alink.com</link>
    <description>Just another WordPress site</description>
    <lastBuildDate>Sun, 21 Apr 2013 22:13:55 +0000</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <generator>http://wordpress.org/?v=3.5.1</generator>

    <item>
        <title>A Title</title>
        <link>http://www.alink.com</link>
        <comments>comments</comments>
        <pubDate>Sun, 21 Apr 2013 22:13:55 +0000</pubDate>
        <dc:creator>aUser</dc:creator>
        <category><![CDATA[Uncategorized]]></category>
        <guid isPermaLink="false">http://www5.uifoundation.org/news/?p=112</guid>
        <description><![CDATA[Post[...]]]></description>
        <content:encoded> Posted October 10, 2013 </content:encoded>
        <wfw:commentRss>http://www.alink.com</wfw:commentRss>
        <slash:comments>0</slash:comments>
    </item>

但我只想在我的转换中显示频道/标题和频道/链接。我正在考虑在所有节点上使用空模板,就像这样

<xsl:template match="channel/* EXCEPTION channel/item/title | channel/item/link" />

我不确定如何声明异常。如果有更好的方法可以做到这一点,我也会对此持开放态度

我真的只是希望输出是 的无序列表item/title,其值为item/link,其他所有内容都隐藏。输出的一个例子是:

<ul>
  <li>
    <a href= "www.aLink.com">A Title</a>
  </li>
</ul> 
4

1 回答 1

5

您可以使用单独的模板来执行此操作,其中一些是空的,并且具有不同的优先级:

<xsl:template match="channel/*" priority="0" /> <!-- swallow these, no output -->

<xsl:template match="channel/item | channel/link" priority="1">
   <xsl:copy-of select="." /> <!-- copy to output -->
</xsl:template>

在 and 的情况下channel/itemchannel/link第二个模板将覆盖第一个模板,因为它的优先级更高。对于 的其他子级channel,第一个模板将触发。

(请注意,模板具有基于匹配模式类型的默认优先级;如果两个具有相同优先级的模板匹配同一个节点,也有一些规则。但是,如果您明确优先级,只要有两个模板可能匹配同一个节点,您不必摆弄那些看不见的规则。)

在没有其他模板指定如何处理<rss><channel>的情况下,将应用默认模板,它们将被处理但不会复制到输出中,文本节点除外。那会有点乱。如果要将这两个元素(但不是它们的所有后代)复制到输出,请尝试以下模板:

<xsl:template match="rss | channel">
  <xsl:copy>
    <xsl:apply-templates />
  </xsl:copy>
</xsl:template>

编辑

既然已经指定了所需的输出,我想说的方法应该完全不同。您的第一个模板可以是:

<xsl:template match="/">
  <ul>
    <xsl:apply-templates select="rss/channel/item" />
  </ul>
</xsl:template>

并且您的第二个模板将每个项目转换为<li>

<xsl:template match="item">
  <li>
    <a href="{link}"><xsl:value-of select="title" /></a> 
  </li>
</xsl:template>

这更像是一种“拉”而不是“推”的方法。您需要输入中的特定节点,并且输入的结构是高度可预测的。通过使用特定的 apply-templates 选择表达式,而不是通用的<xsl:apply-templates select="*" />,您避免了对异常模板的需要,因为只有您选择的节点将被处理。

于 2013-04-22T14:43:43.697 回答