【问题标题】:XPath / XSLT: How to nest siblings until a specific sibling into a new element?XPath / XSLT:如何嵌套兄弟姐妹,直到特定兄弟姐妹进入新元素?
【发布时间】:2019-11-19 15:02:27
【问题描述】:

我有以下 HTML 片段:

<p>
    This is
    <font>start</font>
    just some <i>happy</i> text
    <font>stop</font>
    that might continue here.
</p>

我想用 XSLT 把它变成这样:

<p>
    This is
    <hi>
       just some <i>happy</i> text
    </hi>
    that might continue here.
</p>

因此 font[text() = "start"] 和 font[text() = "stop"] 之间的所有内容(节点和文本和 cmets)都嵌套在新的 hi 元素中。

我试过了:

<!-- identity template here-->

<xsl:template match="font[text()='start']">
    <xsl:element name="hi">
       <!-- FOLLOWING:SIBLING UNTIL THE NEXT font[text()='stop'] -->
       <xsl:value-of select="following-sibling[????]"/>
    </xsl:element>
</xsl:template>

<xsl:template match="font[text()='stop']"><!-- do nothing--></xsl:template>

但是 ????是我找不到正确规则的地方。我玩了半个小时,然后我想问可能会更快。

重要的是它精确到下一站,因为在一个 p 元素中可能有许多这样的结构。

谢谢

【问题讨论】:

  • 这在很大程度上取决于您使用的是 XSLT 1.0 还是 2.0。在 2.0 中您可以使用xsl:for-each-group,在 1.0 中您将不得不使用兄弟递归,这非常棘手。它还取决于您是否可以在一个段落中拥有多个开始/结束对,以及如果它们没有正确配对,您想要做什么。对于 XSLT 问题,请务必说出您需要哪个版本。
  • 谢谢,它是 XSLT 2.0,一个 p 内可以有多个对,但起止标志可以(据我评估数据集)不能嵌套在另一个起止范围内. for-each-group 可能是我正在寻找的,但我还不知道如何。

标签: html xslt xpath


【解决方案1】:

可能是这样的:

<xsl:for-each-group select="node()" group-starting-with="font[.='start']">
  <xsl:for-each-group select="current-group()" group-ending-with="font[.='end']">
    <xsl:choose>
    <xsl:when test="current-group()[self::font[.='start'] and self::font[.='end']">
      <hi>
        <xsl:copy-of select="current-group()[not(self::font)]"/>
      </hi>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="current-group()"/>
    </
  </
</

未测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 2014-07-12
    相关资源
    最近更新 更多