我的XSLT文件存在问题,该文件大致采用以下形式的XML文件:
<model>
<interface>
<doc>text1</doc>
<acc>
<op name="name">
<in>
<doc>text2</doc>
<parameter name="name" type="type">
<doc>text3</doc>
</parameter>
</in>
<out>
<doc>text4</doc>
<parameter name="name" type="type">
<doc>text5</doc>
</parameter>
</out>
<exception name="name">
<doc>text6</doc>
<parameter name="name" type="type">
<doc>text7</doc>
</parameter>
<parameter name="name" type="type">
<doc>text8</doc>
</parameter>
</exception>
</op>
</acc>
<conn>
<op name="name">
<in>
<doc>text9</doc>
<parameter name="name" type="type">
<doc>text10</doc>
</parameter>
</in>
</op>
</conn>
<!-- rest omitted !-->
</interface>
</model>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" indent="yes" />
<xsl:template match="/">
<xsl:text disable-output-escaping='yes'><!DOCTYPE html></xsl:text>
<html>
<head>
<script>
<!-- omitted !-->
</script>
<style>
<!-- omitted !-->
</style>
</head>
<body>
<h2>Title</h2>
<table class="tablesorter" border="1">
<thead>
<tr bgcolor="#9acd32">
<th style="text-align:left">Name</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="//acc|//conn" mode="toc"/>
</tbody>
</table>
<xsl:apply-templates select="//acc|//conn" mode="detail"/>
</body>
</html>
</xsl:template>
<xsl:template name="create_detail_table">
<b>Description:</b> <xsl:value-of select="doc"/>
<h4>Parameters</h4>
<table class="tablesorter" border="1">
<thead>
<tr>
<th style="word-wrap:normal; width:30%">Name</th>
<th style="word-wrap:normal; width:30%">Type</th>
<th style="word-wrap:normal; width:30%">Description</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="parameter"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="acc/op/in" mode="toc">
<tr>
<td><a href="#{../@name}"><xsl:value-of select="../@name"/>foo</a></td>
</tr>
</xsl:template>
<xsl:template match="acc/op/in" mode="detail">
<h3 id="{../@name}"><xsl:value-of select="../@name"/>foo</h3>
<xsl:call-template name="create_detail_table"/>
</xsl:template>
<xsl:template match="parameter">
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="@type"/></td>
<td><xsl:value-of select="doc"/></td>
</tr>
</xsl:template>
<xsl:template match="acc/op/out" mode="detail">
<h3><xsl:value-of select="../@name"/>foo</h3>
<xsl:call-template name="create_detail_table"/>
</xsl:template>
<xsl:template match="acc/op/exception" mode="detail">
<h3><xsl:value-of select="../@name"/>bar</h3>
<xsl:call-template name="create_detail_table"/>
</xsl:template>
<xsl:template match="conn/op/in" mode="detail">
<h3><xsl:value-of select="../@name"/>baz</h3>
<xsl:call-template name="create_detail_table"/>
</xsl:template>
<xsl:template match="model/interface/acc/op/in/parameter/doc" />
</xsl:stylesheet>
我的问题是这个输出看起来很好,除了输出的HTML输出in/doc
,out/doc
,exception/doc
和所有parameter/doc
标签的文本。文档的最顶部(除了第一个in
标签下的那些,为什么?)。
所以基本上doc输出是在文档的顶部(后跟其他看起来正确的输出,带有表和东西):
text4 text5 text6 text7 text8 text9 tex10
为什么会这样?我知道这是因为默认模板,但在我看来,我不是在任何地方匹配这些标签。如果我这样做,我在底部添加了最终模板,匹配model/interface/acc/op/in/parameter/doc
,只是为了捕捉这样的匹配,但它没有任何帮助。
我还尝试覆盖导致此行为的默认模板,例如:
<xsl:template match="text()" />
和
<xsl:template match="*" />
然而,这些都没有区别。我在这里不知所措。
P.S。随意评论我的XSLT风格。我只是学习它而且好奇我是否遵循惯用的XSLT。
答案 0 :(得分:1)
显然,您正在将模板应用于包含要输出的文本节点的节点,但您没有与之匹配的相应模板。在这种情况下,built-in template rules将启动 - 他们的行动是输出所有后代文本值。
我还尝试覆盖导致的默认模板 这种行为,例如:
<xsl:template match="text()" />
如果这不起作用,那么模板已经以不同的模式应用了。事实上,
<xsl:template match="text()" mode="toc"/>
将禁止不需要的文字。
答案 1 :(得分:1)
您拥有<xsl:apply-templates select="//acc|//conn" mode="toc"/>
,但该模式toc
的唯一模板是
<xsl:template match="acc/op/in" mode="toc">
<tr>
<td><a href="#{../@name}"><xsl:value-of select="../@name"/>foo</a></td>
</tr>
</xsl:template>
如果您只想处理该模式的acc/op/in
元素以输出表格行,则不要处理其他元素,因此最简单的修复似乎是使用<xsl:apply-templates select="//acc/op/in" mode="toc"/>
。