【发布时间】:2015-09-11 06:07:25
【问题描述】:
我已经为这个问题苦苦挣扎了 2 天,虽然我相信我已经接近它,但我找不到答案。
我有这个(简化的)自定义代码:
<chapter><subchapter><subchaptersection><module>
<topic>
<title>Title1</title>
<para>Para1.1</para>
<list id="1">
<listitem>
<para>Item1.1</para>
</listitem>
<listitem>
<para>Item2.2</para>
</listitem>
</list>
<para>Para2</para>
<list id="2">
<para>Para2.1</para>
<listitem>
<para>Item2.1</para>
</listitem>
<listitem>
<para>Item2.2</para>
</listitem>
</list>
</subchaptersection></subchapter></chapter>
我有这个 XSL 可以将自定义代码转换为部分 XML(我还有另一个 XSL 可以完成到 XML 的完美转换,为了您的信息,列表也可以出现在“子章节”部分中):
<xsl:template match="chapter"><Chapter><title><xsl:value-of select="title"/></title>
<xsl:apply-templates select="module/topic|subchapter"/>
</Chapter>
</xsl:template>
<xsl:template match="module/topic">
<topic><xsl:attribute name="id">
<xsl:value-of select="normalize-space(title)"/>
</xsl:attribute><title><xsl:value-of select="title"/></title>
<body><xsl:apply-templates select="para|*/para|warning//para|list/listitem/para|introduction//para"/>
</body></topic>
</xsl:template>
<xsl:template match="subchapter">
<topic><xsl:attribute name="id">
<xsl:value-of select="normalize-space(title)"/>
</xsl:attribute><title><xsl:value-of select="title"/></title>
<body><xsl:apply-templates select="introduction//para|subchaptersection|module/topic"/>
</body></topic>
</xsl:template>
<xsl:template match="subchaptersection">
<topic><xsl:attribute name="id">
<xsl:value-of select="normalize-space(title)"/>
</xsl:attribute><title><xsl:value-of select="title"/></title>
<xsl:apply-templates select="introduction//para|module/topic"/></topic>
</xsl:template>
<xsl:template match="para|*/para|warning//para|list/listitem/para|introduction//para">
<xsl:if test="not(ancestor::list) and not (ancestor::warning)">
<p><xsl:value-of select="."/></p>
</xsl:if>
<xsl:if test="ancestor::list">
<xsl:call-template name="LIST"/>
</xsl:if>
</xsl:template>
<xsl:template name="LIST">
<xsl:if test="not (../preceding-sibling::listitem/para)">
<xsl:if test="following-sibling::listitem">
<p><xsl:value-of select="."/></p>
</xsl:if>
<ul>
<xsl:for-each select="self::para/following-sibling::listitem">
<li>
<xsl:value-of select="."/>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
我得到的问题是显示了列表 2,但没有显示列表 1(仅输出空 ul)。从其他几个列表中,我可以观察到仅显示包含列表和第一个列表项之间的 para 的列表(列表 2 就是这种情况)。
我的 XSL 哪里出错了?我总是可以在列表和第一个列表项之间手动插入一个 para,但我确信有一个 XSL 解决方案。
非常感谢您的帮助。
【问题讨论】:
-
我相信你犯了一个错误,因为没有匹配
list的模板并应用它。相反,您调用命名模板来处理来自其先前兄弟para的上下文中的list。这给您的代码增加了可怕的复杂性。 -
非常感谢迈克尔,多亏了您的建议,我才得以成功。我创建了链接到子章节和模块/主题部分的列表模板。它简化了我的列表模板:
<xsl:template match="list"> <xsl:if test="para[parent::list]"> <p><xsl:value-of select="para[parent::list]"/></p> </xsl:if> <ul> <xsl:for-each select="listitem[parent::list]"> <li> <xsl:for-each select="./para"><p><xsl:value-of select="."/></p></xsl:for-each> </li> </xsl:for-each> </ul> </xsl:template> -
Frost,在 cmets 中输入 XML 非常难以阅读……我已将您的 XML 转换为答案。请注意,如果您自己找到了解决方案,您可以在 StackOverflow 上回答您自己的问题。