Haw*_*ick 2 xml xslt rss xml-parsing
我是xsl的新手,我试图在wordpress rss feed的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>
Run Code Online (Sandbox Code Playgroud)
但我想在转换中只显示频道/标题和频道/链接.我正在考虑在所有节点上使用空模板的方法,就像这样
<xsl:template match="channel/* EXCEPTION channel/item/title | channel/item/link" />
Run Code Online (Sandbox Code Playgroud)
我不确定如何声明异常.如果有更好的方法,我也会对此持开放态度
我真的只是希望输出是一个无序的列表item/title,其值为item/link,其他一切都隐藏了.输出的一个例子是:
<ul>
<li>
<a href= "www.aLink.com">A Title</a>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
您可以使用单独的模板执行此操作,其中一些模板为空,并且具有不同的优先级:
<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>
Run Code Online (Sandbox Code Playgroud)
在的情况下,channel/item和channel/link,第二个模板将覆盖第一,因为其优先级较高.对于其他孩子channel,第一个模板将会触发.
(请注意,模板具有基于匹配模式类型的默认优先级;如果两个具有相同优先级的模板与同一节点匹配,则还有一些规则可用.但是,如果在有可能存在两个模板的地方明确优先级匹配相同的节点,你不必摆弄那些看不见的规则.)
在没有其他模板指定如何处理<rss>和<channel>,默认模板将适用,他们将被处理,但不会复制到输出,除了文本节点.那会有点混乱.如果要将这两个元素(但不是所有后代)复制到输出中,请尝试以下模板:
<xsl:template match="rss | channel">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
既然已经指定了所需的输出,我会说这种方法应该是完全不同的.您的第一个模板可以是:
<xsl:template match="/">
<ul>
<xsl:apply-templates select="rss/channel/item" />
</ul>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
并且您的第二个模板将每个项目转换为<li>:
<xsl:template match="item">
<li>
<a href="{link}"><xsl:value-of select="title" /></a>
</li>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
这更像是一种"拉动"而非"推动"的方法.您需要输入中的特定节点,并且输入的结构具有高度可预测性.通过使用特定的apply-templates选择表达式而不是泛型<xsl:apply-templates select="*" />,您可以避免使用异常模板,因为只会处理您选择的节点.