XSLT包装元素和后继同级文本

时间:2018-12-14 09:56:57

标签: xslt

请帮助我用以下同级文字逗号(如果存在逗号)包装img.inline元素:

text <img id="1" class="inline" src="1.jpg"/> another text.
text <img id="2" class="inline" src="2.jpg"/>, another text.

应更改为:

text <img id="1" class="inline" src="1.jpg"/> another text.
text <span class="img-wrap"><img id="2" class="inline" src="2.jpg"/>,</span> another text.

当前,我的XSLT将包装img.inline元素并在范围内添加逗号,现在我要删除以下逗号。

text <span class="img-wrap"><img id="2" class="inline" src="2.jpg"/>,</span>
, <!--remove this extra comma--> another text.

我的XSLT:

<xsl:template match="//img[@class='inline']">
  <xsl:copy>
    <xsl:choose>
      <xsl:when test="starts-with(following-sibling::text(), ',')">
        <span class="img-wrap">
          <xsl:apply-templates select="node()|@*"/>
          <xsl:text>,</xsl:text>
        </span>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:copy>

  <!-- checking following-sibling::text() -->
  <xsl:apply-templates select="following-sibling::text()" mode="commatext"/>
</xsl:template>

<!-- here I want to match the following text, if comma, then remove it -->  
<xsl:template match="the following comma" mode="commatext">
  <!-- remove comma -->
</xsl:template>

我的方法正确吗?还是这应该以不同的方式处理?请建议吗?

1 个答案:

答案 0 :(得分:1)

当前,您正在复制img并将span嵌入其中。此外,您执行<xsl:apply-templates select="node()|@*"/>,这将选择img的子节点(或没有子节点)。对于属性,它将最终将它们添加到span

您实际上不需要这里的xsl:choose,因为您可以将条件添加到match属性中。

<xsl:template match="//img[@class='inline'][starts-with(following-sibling::node()[1][self::text()], ',')]">

请注意,我已更改条件,因为following-sibling::text()选择了img节点之后的所有文本元素。您只想在img节点之后立即获取该节点,但前提是它是文本节点。

此外,假设您有一个与父节点匹配的模板,该模板将选择所有子节点(而不仅仅是xsl:apply-templates个子节点),那么尝试使用img选择以下文本节点可能不是正确的方法。我假设您在这里使用身份模板。

无论如何,请尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="html" indent="no" />

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

<xsl:template match="//img[@class='inline'][starts-with(following-sibling::node()[1][self::text()], ',')]">
  <span class="img-wrap">
    <xsl:copy-of select="." />
    <xsl:text>,</xsl:text>
  </span>
</xsl:template>

<xsl:template match="text()[starts-with(., ',')][preceding-sibling::node()[1][self::img]/@class='inline']">
  <xsl:value-of select="substring(., 2)" />
</xsl:template>

</xsl:stylesheet>