xsl嵌套循环失败

时间:2017-11-18 06:57:15

标签: xml xslt

我有一个xml文件来自我正在使用的口径,并且在嵌套xsl:for-each时遇到了问题。

XML文件:

    <?xml version='1.0' encoding='utf-8'?>
<calibredb>
  <record>
    <title sort="Demon Under the Microscope, The">The Demon Under the Microscope</title>
    <authors sort="Hager, Thomas">
      <author>Thomas Hager</author>
    </authors>
  </record>
  <record>
    <title sort="101 Things Everyone Should Know About Math">101 Things Everyone Should Know About Math</title>
    <authors sort="Zev, Marc &amp; Segal, Kevin B. &amp; Levy, Nathan">
      <author>Marc Zev</author>
      <author>Kevin B. Segal</author>
      <author>Nathan Levy</author>
    </authors>
  </record>
  <record>
    <title sort="Biohazard">Biohazard</title>
    <authors sort="Alibek, Ken">
      <author>Ken Alibek</author>
    </authors>
  </record>
  <record>
    <title sort="Infectious Madness">Infectious Madness</title>
    <authors sort="WASHINGTON, HARRIET">
      <author>Harriet A. Washington</author>
    </authors>
  </record>
  <record>
    <title sort="Poetry Will Save Your Life">Poetry Will Save Your Life</title>
    <authors sort="Bialosky, Jill">
      <author>Jill Bialosky</author>
    </authors>
  </record>
</calibredb>

XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>My Calibre Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Author</th>
      </tr>
      <xsl:for-each select="calibredb/record">
      <tr>
        <td><xsl:value-of select="title" /></td>
        <td><xsl:for-each select="authors"><xsl:value-of select="author" /></xsl:for-each></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

似乎如果存在多位作者,则循环无法继续进行。

有人可以给我一个关于如何正确格式化xsl的建议吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

在XSLT 1.0中,xsl:value-of只会为您提供第一个author的值。

不要在内部for-each中选择authors,而是选择authors/author ...

<xsl:for-each select="authors/author">
    <xsl:value-of select="." />
</xsl:for-each>

您可能还想输出逗号或其他分隔符来分隔值...

<xsl:for-each select="authors/author">
    <xsl:if test="position() > 1">
        <xsl:text>, </xsl:text>
    </xsl:text>
    <xsl:value-of select="."/>
</xsl:for-each>

答案 1 :(得分:0)

这个失败实际上与嵌套循环无关。 请注意,每个record元素只有一个 authors元素, 所以不需要内部xsl:for-each select="authors" (它只会转一圈)。

问题出在其他地方,即value-of指令。 您的案例是关于value-of XSLT 1.0 的奇怪功能的示例, 许多XSLT用户都不知道。

即使select短语检索到多个节点, 然后value-of只打印第一个,而不是整个序列, 和(恕我直言)这不是普通XSLT用户所期望的。

只有在版本 2.0 中才能以更直观的方式制作。

在这种情况下,将打印 XSLT 2.0 中的

value-of指令 整个序列,在它们之间插入指定的分隔符 separator属性。

因此,如果您可以继续使用版本 2.0 ,请写下:

<xsl:for-each select="calibredb/record">
  <tr>
    <td><xsl:value-of select="title" /></td>
    <td><xsl:value-of select="authors/author" separator=", "/></td>
  </tr>
</xsl:for-each>