问题描述
我需要从body元素中删除第一个标题,因为这两个标题具有相同的outputclass值
输入XML:
<topic>
<title outputclass="header">Sample</title>
<topic>
<title outputclass="header">Test</title>
<topic>
<title outputclass="section">Section</title>
<body>
<p outputclass="normal">Solution</p>
</body>
</topic>
</topic>
</topic>
我拥有的XSLT:
<xsl:template match="/*">
<document>
<head>
<title><xsl:value-of select="title[@outputclass='header']"/></title>
</head>
<body>
<xsl:apply-templates/>
</body>
</document>
</xsl:template>
<xsl:template match="topic/title[@outputclass='header'][1]"/>
<xsl:template match="topic">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="body">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="title | p">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
预期输出:
<document>
<head><title>Sample</title></head>
<body>
<p>Test</p>
<p>Section</p>
<p>Solution</p>
</body>
</document>
我需要删除仅考虑相同属性outputclass
的第一个标题。
解决方法
您可以声明一个顶级变量或参数
<xsl:param name="first-output-header" select="/*/descendant::title[@outputclass = 'header'][1]"/>
然后使用
<xsl:template match="$first-output-header"/>
至少在XSLT 3中。我认为在XSLT 2中也是可能的,但是需要深入研究规范或查找实现该“旧”版本的内容。
XSLT 3中的另一个选择是使用累加器对“标头”进行计数并检查值,例如。
<xsl:accumulator name="header-count" as="xs:integer" initial-value="0">
<xsl:accumulator-rule
match="topic/title[@outputclass = 'header']"
select="$value + 1"/>
</xsl:accumulator>
<xsl:mode use-accumulators="header-count"/>
<xsl:template match="topic/title[@outputclass = 'header'][accumulator-before('header-count') = 1]"/>
这同样适用于流式传输。