我确信我的逻辑不正确。 但是,我不确定如何在没有多个 for-each 测试的情况下解决此问题。
也许一劳永逸不是正确的方法? 我将不胜感激任何建议。 此外,我正在使用XSLT 1.0,以防这是必要的信息。
这是我正在使用的 XML:
<?xml version="1.0" encoding="utf-8"?>
<FIGURES>
<FIGURE>
<TITLE>Title 1</TITLE>
<DESC>Description 1</DESC>
<CONTENT>Content 1</CONTENT>
</FIGURE>
<FIGURE>
<TITLE>Title 2</TITLE>
<DESC>Description 2</DESC>
<CONTENT>Content 2</CONTENT>
</FIGURE>
<FIGURE>
<TITLE>Title 2</TITLE>
<DESC>Description 2</DESC>
<CONTENT>Content 2</CONTENT>
</FIGURE>
</FIGURES>
这是我正在尝试的 XSLT:
<xsl:template match="/">
<div class="container">
<ul class="list">
<xsl:for-each select="//FIGURE">
<li>
<a href="#section-{position()}"><h3><xsl:value-of select="TITLE" /></h3></a>
<p><xsl:value-of select="DESC" /></p>
</li>
<div class="content">
<div id="section-{position()}">
<xsl:value-of select="CONTENT" />
</div>
</div>
</xsl:for-each>
</ul>
</div>
</xsl:template>
这是我想要但没有得到的 HTML:
<div class="container">
<ul class="list">
<li>
<a href="#section-1"><h3>Title 1</h3></a>
<p>Description 1</p>
</li>
<li>
<a href="#section-2"><h3>Title 2</h3></a>
<p>Description 2</p>
</li>
<li>
<a href="#section-3"><h3>Title 3</h3></a>
<p>Description 3</p>
</li>
</ul>
<div class="content">
<div id="section-1">
<p>Content 1</p>
</div>
<div id="section-1">
<p>Content 2</p>
</div>
<div id="section-1">
<p>Content 2</p>
</div>
</div>
</div>
这是我得到的,但不想要的 HTML:
<div class="container">
<ul class="list">
<li>
<a href="#section-1"><h3>Title 1</h3></a>
<p>Description 1</p>
</li>
<div class="content">
<div id="section-1">Content 1</div>
</div>
<li>
<a href="#section-2"><h3>Title 2</h3></a>
<p>Description 2</p>
</li>
<div class="content">
<div id="section-2">Content 2</div>
</div>
<li>
<a href="#section-3"><h3>Title 2</h3></a>
<p>Description 2</p>
</li>
<div class="content">
<div id="section-3">Content 2</div>
</div>
</ul>
</div>
编辑 使用肖恩的例子,我想通了。 我只是缺少标签上的选择属性。
<xsl:template match="/">
<div class="container">
<xsl:apply-templates />
</div>
</xsl:template>
<xsl:template match="FIGURES">
<ul class="list">
<xsl:apply-templates select="FIGURE" mode="titles" />
</ul>
<div class="content">
<xsl:apply-templates select="FIGURE" mode="content" />
</div>
</xsl:template>
<xsl:template match="FIGURE" mode="titles">
<li>
<a href="#section-{position()}">
<h3><xsl:value-of select="TITLE" /></h3>
</a>
<p><xsl:value-of select="DESC" /></p>
</li>
</xsl:template>
<xsl:template match="FIGURE" mode="content">
<div id="section-{position()}">
<p><xsl:value-of select="CONTENT" /></p>
</div>
</xsl:template>
这个 XSLT 1.0 样式表...*
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" doctype-system="about:legacy-compat" encoding="UTF-8" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<html>
<body>
<div class="container">
<xsl:apply-templates />
</div>
</body>
</html>
</xsl:template>
<xsl:template match="FIGURES">
<ul class="list">
<xsl:apply-templates mode="titles" />
</ul>
<div class="content">
<xsl:apply-templates mode="content" />
</div>
</xsl:template>
<xsl:template match="FIGURE" mode="titles">
<li>
<a href="#section-{position()}">
<h3><xsl:value-of select="TITLE" /></h3>
</a>
<p><xsl:value-of select="DESC" /></p>
</li>
</xsl:template>
<xsl:template match="FIGURE" mode="content">
<div id="section-{position()}">
<p><xsl:value-of select="CONTENT" /></p>
</div>
</xsl:template>
</xsl:stylesheet>
。当应用于引用的输入文档时,将产生...
<!DOCTYPE html SYSTEM "about:legacy-compat">
<html>
<body>
<div class="container">
<ul class="list">
<li><a href="#section-1"><h3>Title 1</h3></a><p>Description 1</p>
</li>
<li><a href="#section-2"><h3>Title 2</h3></a><p>Description 2</p>
</li>
<li><a href="#section-3"><h3>Title 2</h3></a><p>Description 2</p>
</li>
</ul>
<div class="content">
<div id="section-1">
<p>Content 1</p>
</div>
<div id="section-2">
<p>Content 2</p>
</div>
<div id="section-3">
<p>Content 2</p>
</div>
</div>
</div>
</body>
</html>
更新
如果你没有使用 xsl:strip-space(你应该,正如我在解决方案中给你的),或者如果由于某种原因,你在 FIGURE 元素之间穿插了其他节点,那么这个样式表会给你一个更健壮的解决方案......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" doctype-system="about:legacy-compat" encoding="UTF-8" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<html>
<body>
<div class="container">
<xsl:apply-templates />
</div>
</body>
</html>
</xsl:template>
<xsl:template match="FIGURES">
<ul class="list">
<xsl:apply-templates mode="titles" />
</ul>
<div class="content">
<xsl:apply-templates mode="content" />
</div>
</xsl:template>
<xsl:template match="FIGURE" mode="titles">
<li>
<a href="#section-{count(preceding-sibling::FIGURE)+1}">
<h3><xsl:value-of select="TITLE" /></h3>
</a>
<p><xsl:value-of select="DESC" /></p>
</li>
</xsl:template>
<xsl:template match="FIGURE" mode="content">
<div id="section-{count(preceding-sibling::FIGURE)+1}">
<p><xsl:value-of select="CONTENT" /></p>
</div>
</xsl:template>
</xsl:stylesheet>
不确定这是否是最有效的方法,但应该解决目的:
<xsl:template match="/">
<xsl:apply-templates select="./FIGURES"/>
</xsl:template>
<xsl:template match="FIGURES">
<html>
<body>
<div class="container">
<ul class="list">
<xsl:apply-templates select="//FIGURE"/>
</ul>
<div class="content">
<xsl:apply-templates select="//CONTENT"/>
</div>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="CONTENT">
<div id="section-{position()}">
<p><xsl:value-of select="."/></p>
</div>
</xsl:template>
<xsl:template match="FIGURE">
<li>
<a href="#section-{position()}">
<h3><xsl:value-of select="./TITLE"/></h3>
</a>
<p><xsl:value-of select="./DESC"/></p>
</li>
</xsl:template>