3

我有一个 XML 文档,其中包含以下示例摘录:

<p>
    Some text <GlossaryTermRef href="123">term 1</GlossaryTermRef><GlossaryTermRef href="345">term 2</GlossaryTermRef>.
</p>

我正在使用 XSLT 使用以下模板将其转换为 XHTML:

<xsl:template match="GlossaryTermRef">
    <a href="#{@href}" class="glossary">
        <xsl:apply-templates select="node()|text()"/>
    </a>
</xsl:template>

这很好用,但是GlossaryTermRef如果它们彼此相邻,我需要在两个元素之间插入一个空格吗?

有没有办法检测当前节点和下一个兄弟节点之间是否有空格或文本?我不能总是插入空格GlossaryTermRef项,因为它后面可能跟着一个标点符号。

4

3 回答 3

3

我设法自己解决了这个问题,我修改模板如下:

<xsl:template match="GlossaryTermRef">
    <a href="#{@href}" class="glossary">
        <xsl:apply-templates select="node()|text()"/>
    </a>
    <xsl:if test="following-sibling::node()[1][self::GlossaryTermRef]">
        <xsl:text> </xsl:text>
    </xsl:if>
</xsl:template>

任何人都可以提出更好的方法,或者看到这个解决方案有什么问题吗?

于 2012-04-16T19:12:06.743 回答
2

首先,“node()|text()”是“node()”的冗长等价物。也许您的意思是“*|node()”,它将选择元素和文本子项,而不是评论或 PI。

您的解决方案可能与任何解决方案一样好。另一个是使用分组:

<xsl:for-each-group select="node()" group-adjacent="boolean(self::GlossaryTermRef)">
  <xsl:choose>
    <xsl:when test="current-grouping-key()">
      <xsl:for-each select="current-group()">
        <xsl:if test="position() gt 1"><xsl:text> </xsl:text></xsl:if>
        <xsl:apply-templates select="."/>
      </xsl:for-each>
    </xsl:when>
    <xsl:otherwise>
     <xsl:apply-templates select="current-group()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each-group>

不,那一点都不漂亮。

我的下一个尝试是使用兄弟递归(父母对第一个孩子应用模板,每个孩子对紧随其后的兄弟应用模板),但我认为这也不会是一个改进。

于 2012-04-16T21:56:40.280 回答
0

这个如何?你感觉怎么样?

<xsl:template match="GlossaryTermRef">
<a href="#{@href}" class="glossary">
<xsl:apply-templates select="node()|text()"/>
</a>
</xsl:template>
于 2013-08-23T12:23:23.427 回答