我需要xslt
使用<media>
标记作为幻灯片显示处理一系列图像,将单个图像作为内嵌图像处理。我有逻辑来查找被<media>
标记包围的<p>
,但扩展它来处理所有非<media>
标记是单调乏味的。我怎样才能编写某种适用于xslt 1.0的not(p)
逻辑?
这是xslt(我删除了完整的调用模板代码,因为它并不重要):
<xsl:template name="textImage">
<xsl:param name="paragraphs"/>
<xsl:variable name="paragraphCount" select="count($paragraphs)"/>
<xsl:for-each select="$paragraphs">
<xsl:choose>
<xsl:when test="mediaReference">
<xsl:choose>
<!--single media block-->
<xsl:when test="ancestor::table or position() = $paragraphCount or (position() = 1 and (generate-id(following-sibling::*[1]) != generate-id(following-sibling::media[1]))) or (generate-id(preceding-sibling::p[1]/following-sibling::media[1]) = generate-id(current()) and generate-id(following-sibling::p[1]/preceding-sibling::media[1]) = generate-id(current()))">
<xsl:call-template name="imageNode"/>
</xsl:when>
<!--two more pam:media blocks for a carousel-->
<xsl:otherwise>
<xsl:choose>
<xsl:when test="generate-id(preceding-sibling::p[1]/following-sibling::media[1]) = generate-id(current())">
<xsl:call-template name="firstImageNode"/>
</xsl:when>
<xsl:when test="generate-id(following-sibling::p[1]/preceding-sibling::media[1]) = generate-id(current())">
<xsl:call-template name="lastImageNode"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="imageNode"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="textNode"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
以下是一些示例xml:
<?xml version="1.0" encoding="utf-8"?>
<message>
<article xml:lang="en-US">
<body>
<h2>What a Chicken!</h2>
<media>
<mediaReference refid="BA_chicken1.jpg"/>
</media>
<ol>
<li>
<p>Place chicken breast side down.</p>
</li>
</ol>
<media>
<mediaReference refid="BA_chicken2.jpg"/>
</media>
<media>
<mediaReference refid="BA_chicken3.jpg"/>
</media>
<p>More about chickens</p>
<media>
<mediaReference refid="BA_chicken4.jpg"/>
</media>
<p>The End</p>
</body>
</article>
</message>
正确的输出类似于:
<h2>What a Chicken!</h2>
<img src="BA_chicken1.jpg">
<ol><li>
<p>Place chicken breast side down.</p>
</li></ol>
<div class="slideshow">
<img src="BA_chicken2.jpg">
<img src="BA_chicken3.jpg">
</div>
<p>More about chickens</p>
<img src="BA_chicken4.jpg">
<p>The End</p>
答案 0 :(得分:1)
也许您会从更好地使用匹配模板的方法中受益。如果您从身份模板开始,您将拥有单独的模板以匹配您的各种情况,例如它是个人还是组,并且对于连续的模板,您有一个递归模板来一次处理一个连续元素。
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:pam="pam">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<!-- Ignore media elements with direct preceding siblings as these are processed elsewhere -->
<xsl:template match="pam:media[preceding-sibling::*[1][self::pam:media]]" priority="2" />
<!-- First of a group -->
<xsl:template match="pam:media[following-sibling::*[1][self::pam:media]]">
<div class="image">
<xsl:apply-templates select="self::*" mode="image" />
</div>
</xsl:template>
<!-- Individual -->
<xsl:template match="pam:media">
<xsl:apply-templates select="self::*" mode="image" />
</xsl:template>
<!-- Template that actually creates the image -->
<xsl:template match="pam:media" mode="image">
<img src="{pam:mediaReference/@pam:refid}" />
<xsl:apply-templates select="following-sibling::*[1][self::pam:media]" mode="image" />
</xsl:template>
<!-- Identity Template -->
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我注意到您的XSLT似乎区分了组中的第一个和最后一个元素,尽管您的输出XML没有显示这一点。调整此答案以解决这个问题的一种方法是修改&#34;图像&#34;模式模板,用于保持运行计数,以允许它检查它是否是组中的第一个或最后一个节点。
例如,此更新的模板会在第一个和最后一个元素上添加不同的类:
<xsl:template match="pam:media" mode="image">
<xsl:param name="position" select="1" />
<xsl:variable name="nextElement" select="following-sibling::*[1][self::pam:media]" />
<img src="{pam:mediaReference/@pam:refid}">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="$position = 1 and $nextElement">first image</xsl:when>
<xsl:when test="$position > 1 and not($nextElement)">last image</xsl:when>
<xsl:otherwise>image</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</img>
<xsl:apply-templates select="$nextElement" mode="image">
<xsl:with-param name="position" select="$position + 1" />
</xsl:apply-templates>
</xsl:template>