using XSLT to display image series with captions in XHTML

时间:2015-07-29 00:07:35

标签: xslt

I'm trying to display a series of images each with its own caption using XSLT. I've coded the images and the captions by nesting var children = ['Kangaroo', 'Alligator', 'Ardvark', 'Ant', 'Bear', 'Bat', 'Cat', 'Cow']; children.sort(); var aZ = []; for (i=0; i < children.length; i++) { var child = children[i]; aZ.push({ name: child }); } for (i=0; i < aZ.length; i++) { var child = aZ[i]; var cName = child.name; var cLetter = cName.charAt(0); document.write('<li>' + cLetter +'</li>'); document.write('<li>' + cName +'</li>'); } and then <img> within but the resultant html does not display as intended (the captions are not lining up with corresponding images). Is there a way to nest <figcaption> for the captions within the images? Here's the XSLT:

<xsl: for-each>

Here's the corresponding XML:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"    
    exclude-result-prefixes="xs"
    version="2.0">    
    <xsl:output method="html"/>      
    <xsl:template match="letter">       
        <html>
            <head>
                <style type="text/css">
                    #wrapper {min-height: 100%;}                    
                    #figcaption {
                    text-align: left;
                    }
                    #main {
                    padding-top: 15px;;
                    width: 1200px;
                    }                    
                </style>
            </head>
            <body>
                <div id="wrapper">                    
                    <div id="images">
                        <figure>                                
                            <xsl:if test="image">                                    
                                <xsl:for-each select="image/@xlink:href">                                        
                                    <img>                                            
                                        <xsl:attribute name="src">                                                
                                            <xsl:value-of select="."/>                                                
                                        </xsl:attribute>                                            
                                    </img>                                        
                                </xsl:for-each>                                    
                            </xsl:if>                                
                            <xsl:if test="image/@label">                                    
                                <xsl:for-each select="image/@label">                                        
                                    <figcaption><xsl:value-of select="."/></figcaption>                                        
                                </xsl:for-each>                                    
                            </xsl:if>                                
                        </figure>
                    </div> 
                </div>
            </body>
        </html>
    </xsl:template>   
</xsl:stylesheet>

My desired output in html is basically this for each image:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="XSLT.xsl"?>
<letter xmlns:xlink="http://www.w3.org/1999/xlink">    
    <image label="page 1" xlink:href="http://tinyurl.com/nu7zmhc"/> 
    <image label="page 2" xlink:href="http://tinyurl.com/pysyztr"/> 
    <title>Letter from Shawn Schuyler</title>   
    <date>1963-06-30</date>     
    <language>English</language>    
    <creator>       
        <firstName>William</firstName>      
        <lastName>Schultz</lastName>
        <street>Unites States Disciplinary Barracks</street>            
        <city>Fort Leavenworth</city>           
        <state abbr="KS">Kansas</state>     
    </creator>      
</letter>

2 个答案:

答案 0 :(得分:1)

或者简单地说:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
exclude-result-prefixes="xlink">

<xsl:template match="/letter">
    <html>
        <head>
            <style type="text/css">
            #wrapper {min-height: 100%;}
            #figcaption {
            text-align: left;
            }
            #main {
            padding-top: 15px;;
            width: 1200px;
            }
        </style>
        </head>
        <body>
            <div id="wrapper">
                <div id="images">
                    <xsl:for-each select="image">
                        <figure>
                            <img src='{@xlink:href}'/>
                            <figcaption>
                                <xsl:value-of select="@label"/>
                            </figcaption>
                        </figure>  
                    </xsl:for-each>
                </div>
            </div>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

注意:

  1. 使用xsl:for-each并没有错,尤其是在使用xsl:element时 像这样的简单案例;

  2. 当您可以使用文字结果元素时, 使用create table comments ( id SERIAL PRIMARY KEY, message VARCHAR, parent_id INTEGER REFERENCES comments(id) ); /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var integer * * @ORM\Column(name="parent_id", type="integer") * @ORM\OneToMany(targetEntity="Comment", mappedBy="id") */ private $parent_id; 时出现了问题。虽然XSLT自然是冗长的,但使用属性值模板可以减少代码(非常有意义,正如您在本案例中所见)。

答案 1 :(得分:0)

试试这个:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
  <xsl:output method="html" indent="yes" />
  <xsl:template match="letter">
    <html>
      <head>
        <style type="text/css">
          #wrapper {min-height: 100%;}
          #figcaption {
          text-align: left;
          }
          #main {
          padding-top: 15px;;
          width: 1200px;
          }
        </style>
      </head>
      <body>
        <div id="wrapper">
          <div id="images">
            <xsl:apply-templates select="./image"></xsl:apply-templates>
          </div>
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="letter/image">
    <xsl:element name="figure">
      <xsl:element name="img">
        <xsl:attribute name="src">
          <xsl:value-of select="./@xlink:href"/>
        </xsl:attribute>
      </xsl:element>
      <xsl:apply-templates select="./@label"></xsl:apply-templates>
    </xsl:element>
  </xsl:template>
  <xsl:template match="letter/image/@label">
    <xsl:element name="figcaption">
      <xsl:value-of select="."/>
      </xsl:element>
    </xsl:template>
</xsl:stylesheet>

xsl:apply-templates表示应该放置与select中指定的模式匹配的任何内容(使用点显示当前元素的上下文)。

xsl:template根据match中给出的路径与源文档进行匹配。任何匹配都是并行处理的,然后根据apply-templates元素指示的位置拼接在一起。

注意:具有output="html"的XSLT引擎可能会对您的img元素产生不同的影响。在HTML5中,img元素被定义为不需要关闭标记(或自动关闭),因此引擎不会关闭该标记。关于这种不一致是否是一个好选择的争论可以在整个网络中找到。

参考:Are (non-void) self-closing tags valid in HTML5?

有关此for-each备用方法的好文章可在此处找到:http://gregbee.ch/blog/using-xsl-for-each-is-almost-always-wrong 您会发现,使用XLST,一旦模板的概念点击您的代码将变得更短,维护更简单。