通过XSLT遍历多个嵌套节点

时间:2015-09-19 05:49:15

标签: xml xslt

我有一个从TEI XML文档生成的站点,其中一个元素是顶部的一组缩略图,取自文件中存在的jpgs数。包含这些jpgs的XML如下:

<sourceDoc xml:id="TextContent">
    <surfaceGrp xml:id="wall" n="South Wall">
        <surface xml:id="p.1" n="panel">
            <label>Verse 27</label>
            <graphic url="sw_test_1.jpg"/>
        </surface>
        <surface xml:id="EETS.T.30">
            <label>Verse 30</label>
            <graphic url="sw_test_2.jpg"/>
        </surface>
        <surface xml:id="EETS.T.27">
            <label>Verse 27</label>
            <graphic url="sw_test_3.jpg"/>
        </surface>
        <surface xml:id="EETS.T.56">
            <label>Verse 56</label>
            <graphic url="sw_test_4.jpg"/>
        </surface>
        <surface xml:id="EETS.T.57">
            <label>Verse 57</label>
            <graphic url="sw_test_5.jpg"/>
        </surface>
        <surface xml:id="EETS.T.58">
            <label>Verse 58</label>
            <graphic url="sw_test_6.jpg"/>
        </surface>
        <surface xml:id="EETS.T.59">
            <label>Verse 59</label>
            <graphic url="sw_test_7.jpg"/>
        </surface>
    </surfaceGrp>
</sourceDoc>

我正在将以下相当混乱的XSL应用于它,它与上面存在的代码配合使用并利用tei命名空间:

    <xsl:template name="menuWidth">
        <xsl:choose>
            <xsl:when test="//tei:sourceDesc[1]/@xml:id='Clopton_Chantry_Chapel'">
                <xsl:attribute name="id">panel</xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="id">page</xsl:attribute>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="menuHeader">
        <xsl:variable name="filename_length" select="string-length(tei:graphic/@url)"/>
        <h1 class="menuHeader">
            <xsl:call-template name="menuWidth"/>

            <div id="centerMenu">
                <xsl:apply-templates select=".././/tei:graphic" mode="list"/>
            </div>

            <xsl:variable name="last_block" as="xs:integer">
                <xsl:choose>
                    <xsl:when test="//tei:sourceDesc[1]/@xml:id='Clopton_Chantry_Chapel'">
                        <xsl:value-of select="count(../preceding-sibling::tei:surfaceGrp)"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="count(../../preceding-sibling::tei:surfaceGrp)"/>
                    </xsl:otherwise>
                </xsl:choose>     
            </xsl:variable>

        <xsl:variable name="next_block" as="xs:integer">
            <xsl:choose>
                <xsl:when test="//tei:sourceDesc[1]/@xml:id='Clopton_Chantry_Chapel'">
                    <xsl:value-of select="count(../following-sibling::tei:surfaceGrp)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="count(../../following-sibling::tei:surfaceGrp)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="total_blocks">
            <xsl:value-of select="../last()"/>
        </xsl:variable>

        <xsl:variable name="group_position" as="xs:integer">
            <xsl:choose>
                <xsl:when test="//tei:sourceDesc[1]/@xml:id='Clopton_Chantry_Chapel'">
                    <xsl:value-of
                        select="../../count(tei:surfaceGrp) - count(../following-sibling::node()/position())"
                    />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of
                        select="../../../count(tei:surfaceGrp) - count(../following-sibling::node()/position())"
                    />
                </xsl:otherwise>
            </xsl:choose>     
        </xsl:variable>

        <xsl:variable name="last_item_id">
            <xsl:choose>
                <xsl:when test="//tei:sourceDesc[1]/@xml:id='Clopton_Chantry_Chapel'">
                    <xsl:value-of
                        select="../../tei:surfaceGrp[last()]/tei:surface[last()]/@xml:id"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of
                        select="../../../tei:surfaceGrp[last()]/tei:surfaceGrp[last()]/tei:surface[last()]/@xml:id"
                    />
                </xsl:otherwise>
            </xsl:choose>            
        </xsl:variable>

        <div id="rightMenu">
            <xsl:choose>
                <xsl:when test="count(preceding-sibling::tei:surface)+1 &gt; 1">
                    <span class="menuitem" id="previousItem">
                        <a class="nav_link">
                            <xsl:attribute name="href">
                                <xsl:value-of
                                    select="concat(substring(preceding-sibling::*[1]/tei:graphic/@url,1,($filename_length - 4)),'.html')"/>
                                <!--<xsl:value-of select="concat(preceding-sibling::*[1]/@xml:id,'.html')"/></xsl:attribute>-->
                            </xsl:attribute> Previous</a>
                    </span>
                </xsl:when>
                <xsl:when test="count(../preceding-sibling::tei:surfaceGrp)+1 &gt; 1">
                    <span class="menuitem" id="previousItem">
                        <a class="nav_link"><xsl:attribute name="href">
                            <xsl:value-of
                                select="concat(substring(../../tei:surfaceGrp[$last_block]/tei:surface[last()]/tei:graphic/@url,1,($filename_length - 4)),'.html')"
                            />
                        </xsl:attribute>Previous</a>
                    </span>
                </xsl:when>
                <xsl:otherwise>
                    <span class="menuitem" id="previousItem">
                        <a class="nav_link">Previous</a>
                    </span>
                </xsl:otherwise>
            </xsl:choose>

            <xsl:choose>
                <xsl:when test="$last_item_id = @xml:id">
                    <span class="menuitem" id="nextItem">
                        <a class="nav_link">Next</a>
                    </span>
                </xsl:when>
                <xsl:when test="position() = last()">
                    <span class="menuitem" id="nextItem">
                        <a class="nav_link"><xsl:attribute name="href"><xsl:value-of
                            select="concat(substring(../../tei:surfaceGrp[$group_position+1]/tei:surface[1]/tei:graphic/@url,1,($filename_length - 4)),'.html')"
                        /></xsl:attribute>Next</a>
                    </span>
                </xsl:when>
                <xsl:when test="not(position() = last())">
                    <span class="menuitem" id="nextItem">
                        <a class="nav_link"><xsl:attribute name="href"><xsl:value-of
                            select="concat(substring(following-sibling::*[1]/tei:graphic/@url,1,($filename_length - 4)),'.html')"
                        /></xsl:attribute>Next</a>
                    </span>
                </xsl:when>
                <xsl:otherwise/>
            </xsl:choose>
        </div>
    </h1>
</xsl:template>

<xsl:template match="tei:graphic"/>

<xsl:template match="tei:graphic" mode="list">
    <span class="menuitem" id="image_thumbnail">
        <a class="nav_link">
            <xsl:attribute name="href">
                <xsl:value-of select="concat(substring(@url,1,string-length(@url)-4),'.html')"/>
            </xsl:attribute>
            <img class="thumbnail">
                <xsl:attribute name="src">
                    <xsl:value-of
                        select="concat('../../',$title_folder,'/',$witness,'/',$thumbnail_folder,'/',substring(@url,1,string-length(@url)-4),'-thumbnail.jpg')"
                    />
                </xsl:attribute>
                <xsl:attribute name="alt">
                    <xsl:value-of select="../tei:label"/>
                </xsl:attribute>
            </img>
        </a>
    </span>
</xsl:template>

这个代码适用于单个surfaceGrp语句,如第一张图所示,但是当我必须将surfaceGrp包装在另一个surfaceGrp中时,它只适用于最里面的surfaceGrp { {1}}。我的想法是,如果我通过../变量中的group_position再上升一级,它将显示所有项目,但这似乎不起作用,如第二张图所示。

First Picture Second Picture

理想情况下,我希望XSL生成的HTML看起来像这样,每个项目的缩略图显示:

<div id="centerMenu">
<span class="menuitem" id="image_thumbnail">
    <a class="nav_link" href="sw_test_1.jpg">
        <img class="thumbnail" src="../../Quis_Dabit/Clopton/Thumbnails/sw_test_1-thumbnail.jpg" alt="First Panel" />
    </a>
</span>
<span class="menuitem" id="image_thumbnail">
    <a class="nav_link" href="sw_test_2.html">
        <img class="thumbnail" src="../../Quis_Dabit/Clopton/Thumbnails/sw_test_2-thumbnail.jpg" alt="Second Panel" />
    </a>
</span>
<span class="menuitem" id="image_thumbnail">
    <a class="nav_link" href="sw_test_3.html">
        <img class="thumbnail" src="../../Quis_Dabit/Clopton/Thumbnails/sw_test_3-thumbnail.jpg" alt="Third Panel" />
    </a>
</span>
<span class="menuitem" id="image_thumbnail">
    <a class="nav_link" href="sw_test_4.html">
        <img class="thumbnail" src="../../Quis_Dabit/Clopton/Thumbnails/sw_test_4-thumbnail.jpg" alt="Fourth Panel" />
    </a>
</span>
<span class="menuitem" id="image_thumbnail">
    <a class="nav_link" href="sw_test_5.html">
        <img class="thumbnail" src="../../Quis_Dabit/Clopton/Thumbnails/sw_test_5-thumbnail.jpg" alt="Fifth Panel" />
    </a>
</span>
<span class="menuitem" id="image_thumbnail">
    <a class="nav_link" href="sw_test_6.html">
        <img class="thumbnail" src="../../Quis_Dabit/Clopton/Thumbnails/sw_test_6-thumbnail.jpg" alt="Sixth Panel" />
    </a>
</span>
</div>
<div id="rightMenu">
    <span class="menuitem" id="previousItem">
        <a class="nav_link">Previous</a>
    </span>
    <span class="menuitem" id="nextItem">
        <a class="nav_link" href="sw_test_2.html">Next</a>
    </span>
</div>

即使surfaceGrp换行发生在列表中间:

<sourceDoc xml:id="TextContent">
    <surfaceGrp xml:id="wall" n="West Wall">
        <surface xml:id="EETS.T.60">
            <label>Verse 60</label>
            <graphic url="ww_test_1.jpg"/>
        </surface>
        <surface xml:id="EETS.T.63">
            <label>Verse 63</label>
            <graphic url="ww_test_2.jpg"/>
        </surface>
        <surface xml:id="EETS.T.65">
            <label>Verse 65</label>
            <graphic url="ww_test_3.jpg"/>
        </surface>
    </surfaceGrp>
    <surfaceGrp xml:id="wall" n="West Wall">
        <surface xml:id="EETS.T.66">
            <label>Verse 66</label>
            <graphic url="ww_test_4.jpg"/>
        </surface>
        <surface xml:id="EETS.T.68">
            <label>Verse 68</label>
            <graphic url="ww_test_5.jpg"/>
        </surface>
        <surface xml:id="EETS.T.69">
            <label>Verse 69</label>
            <graphic url="ww_test_6.jpg"/>
        </surface>
    </surfaceGrp>
</sourceDoc>

修改我的代码以实现此目的的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

我的问题仍然不清楚,所以这不是你想要的,但它可能会指出你正确的方向。

这个XSLT 2.0样式表....

<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

<xsl:output method="html" version="5" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
  <html>
    <head>
      <title>Source Doc</title>
    </head>
    <body>
      <xsl:apply-templates select="sourceDoc" />
    </body>
  </html>
</xsl:template>

<xsl:template match="sourceDoc">
  <div id="centerMenu">
    <xsl:apply-templates select="surfaceGrp/surface"/>
  </div>
</xsl:template>

<xsl:template match="surface">
  <span class="menuitem" id="{@xml:id}">
    <a class="nav_link" href="{graphic/@url}">
      <img
          class="thumbnail"
          src="{graphic/@url}"
          alt="First Panel" />
    </a>
  </span>
</xsl:template>

</xsl:transform>

...将转换此输入xml文档...

<sourceDoc xml:id="TextContent">
    <surfaceGrp xml:id="wall" n="South Wall">
        <surface xml:id="p.1" n="panel">
            <label>Verse 27</label>
            <graphic url="sw_test_1.jpg"/>
        </surface>
        <surface xml:id="EETS.T.30">
            <label>Verse 30</label>
            <graphic url="sw_test_2.jpg"/>
        </surface>
        <surface xml:id="EETS.T.27">
            <label>Verse 27</label>
            <graphic url="sw_test_3.jpg"/>
        </surface>
        <surface xml:id="EETS.T.56">
            <label>Verse 56</label>
            <graphic url="sw_test_4.jpg"/>
        </surface>
        <surface xml:id="EETS.T.57">
            <label>Verse 57</label>
            <graphic url="sw_test_5.jpg"/>
        </surface>
        <surface xml:id="EETS.T.58">
            <label>Verse 58</label>
            <graphic url="sw_test_6.jpg"/>
        </surface>
        <surface xml:id="EETS.T.59">
            <label>Verse 59</label>
            <graphic url="sw_test_7.jpg"/>
        </surface>
    </surfaceGrp>
</sourceDoc>

...进入这个html输出文档...

<!DOCTYPE HTML>
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Source Doc</title>
   </head>
   <body>
      <div id="centerMenu">

        <span class="menuitem" id="p.1">
          <a class="nav_link" href="sw_test_1.jpg">
            <img class="thumbnail" src="sw_test_1.jpg" alt="First Panel">
          </a>
        </span>

        <span class="menuitem" id="EETS.T.30">
          <a class="nav_link" href="sw_test_2.jpg">
            <img class="thumbnail" src="sw_test_2.jpg" alt="First Panel">
          </a>
        </span>

        <span class="menuitem" id="EETS.T.27">
          <a class="nav_link" href="sw_test_3.jpg">
            <img class="thumbnail" src="sw_test_3.jpg" alt="First Panel">
          </a>
        </span>

        <span class="menuitem" id="EETS.T.56">
          <a class="nav_link" href="sw_test_4.jpg">
            <img class="thumbnail" src="sw_test_4.jpg" alt="First Panel">
          </a>
        </span>

        <span class="menuitem" id="EETS.T.57">
          <a class="nav_link" href="sw_test_5.jpg">
            <img class="thumbnail" src="sw_test_5.jpg" alt="First Panel">
          </a>
        </span>

        <span class="menuitem" id="EETS.T.58">
          <a class="nav_link" href="sw_test_6.jpg">
            <img class="thumbnail" src="sw_test_6.jpg" alt="First Panel">
          </a>
        </span>

        <span class="menuitem" id="EETS.T.59">
          <a class="nav_link" href="sw_test_7.jpg">
            <img class="thumbnail" src="sw_test_7.jpg" alt="First Panel">
          </a>
        </span>

      </div>
   </body>
</html>