我正在为学校项目建立一个博客网站。博客文章的内容由许多元素组成,每个元素可以是纯文本,链接,图像或视频。所有这些元素必须按照它们在XML文件中存储的顺序显示,并且每个元素都将以新的<p>
标记显示。
因此,我们的想法是以某种方式循环所有这些元素,每次迭代都应执行`xsl:choose
来决定如何显示当前迭代的元素。
以此代码为例:当元素为b:blogPostContent/b:blogPostText
类型时,如何使其仅执行TEXT部分,当元素为b:blogPostContent/b:blogPostLink
时,如何使其执行LINK部分?
<xsl:for-each select="b:blogPostContent/*">
<p>
<!--TEXT-->
<xsl:value-of select="."/>
<!--LINK-->
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="./@target"/>
</xsl:attribute>
<xsl:attribute name="target">
_blank
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</p>
</xsl:for-each>
答案 0 :(得分:1)
使用choose
这样的元素:
<xsl:choose>
<xsl:when test="name() = 'b:blogPostText'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="./@target"/>
</xsl:attribute>
<xsl:attribute name="target">_blank</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
另一种可能性是在单独的模板中匹配这些元素。假设您的模板与b:blogPostContent
元素匹配(实际上,您没有显示输入XML的结构):
<xsl:template match="b:blogPostContent">
<p>
<xsl:apply-templates select="b:blogPostText|b:blogPostLink"/>
</p>
</xsl:template>
<xsl:template match="b:blogPostText">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="b:blogPostLink">
<a>
<xsl:attribute name="href">
<xsl:value-of select="./@target"/>
</xsl:attribute>
<xsl:attribute name="target">_blank</xsl:attribute>
<xsl:value-of select="."/>
</a>
</xsl:template>
请注意,<xsl:element name="a">
与<a>
完全相同。这就是为什么我缩短了符号。 (无论如何,这是不一致的,因为你没有写<xsl:element name="p">
)。
答案 1 :(得分:1)
因此,我们的想法是以某种方式循环所有这些元素,每次迭代都应执行
xsl:choose
来决定如何显示当前迭代的元素。
这个想法并不坏,但是受到强制性思维模式的驱使。 XSLT不是一种命令式语言,大多数时候最好遵循声明性模式。
<xsl:template match="b:blogPostContent">
<article>
<xsl:apply-templates select="*" mode="wrap_p" />
</article>
</xsl:template>
<xsl:template select="*" mode="wrap_p">
<p>
<xsl:apply-templates select="." />
</p>
</xsl:template>
<xsl:template match="b:blogPostText">
<xsl:value-of select="." />
</xsl:template>
<xsl:template match="b:blogPostLink">
<a href="{@target}" target="_blank">
<xsl:value-of select="."/>
</a>
</xsl:template>
<xsl:template match="b:blogPostList">
<ul>
<xsl:apply-templates select="*" />
</ul>
</xsl:template>
等等。
通过这种方式,您可以获得小型,专用的模块化模板,这些模板仅执行一件事,而XSLT引擎决定哪个模板最适合哪个输入节点。
请注意,您永远不必编写<xsl:element>
或<xsl:attribute>
,除非您想动态创建它们(例如,基于变量的名称)。如果您想在输出中输入<a>
,只需在XSLT中添加<a>
。