使用XPATH在两个处理指令之间选择所有文本节点 [英] Selecting all text nodes in between two processing instructions with XPATH

查看:60
本文介绍了使用XPATH在两个处理指令之间选择所有文本节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些以下XML:

<content>
  <p>
    <?change-addition-start?>
    test 
    <em>test</em>
    <strong>test</strong>
    <?change-addition-end?>
  </p>
</content>

我正在尝试在<?change-addition-start?> PI之后添加< ins> 标记,并在;/ins> 标记放在<?change-addition-end?> 之前,因此基本上只是试图在< ins>中将这两个PI之间的内容包装起来标记.有没有办法用XSLT/XPATH做到这一点?这些标签之间可以包含任何内容,因此无法针对我上面的测试用例进行特定设置.

I am trying to add an <ins> tag after the <?change-addition-start?> PI, and a closing </ins> tag before the <?change-addition-end?>, so basically just trying to wrap anything between those two PI's in an <ins> tag. Is there a way to achieve this with XSLT/XPATH? There can be any content in between those tags, so setting up something specific to my test case above will not be possible.

推荐答案

我建议使用Maring Honnen在第一条评论中建议的 xal:for-each-group .其他XPath方法允许您在两个处理指令之间选择内容,但是很难将其嵌入到xslt样式表中,该样式表也应该做其他事情,例如同时复制现有结构.这里是使用for-each-group的最小方法:

I recommend using xal:for-each-group as suggested in the first comment by Maring Honnen. The other XPath approaches allow you to select the content between two processing instructions, but it will be hard to embed that in an xslt stylesheet that should do other things as well, like copying existing structure at the same time. Here a minimal approach using for-each-group:

xquery version "1.0-ml";

let $xml :=
  <content>
    <p>
      before
      <?change-addition-start?>
      test 
      <em>test</em>
      <strong>test</strong>
      <?change-addition-end?>
      after
    </p>
  </content>

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

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

    <xsl:template match="*[processing-instruction()]">
      <xsl:variable name="parent" select="." />

      <xsl:for-each-group select="node()" group-starting-with="processing-instruction()">
        <xsl:choose>
          <xsl:when test="self::processing-instruction('change-addition-start')">
            <ins>
              <xsl:apply-templates select="current-group()" mode="identity"/>
            </ins>
          </xsl:when>

          <xsl:otherwise>
            <xsl:apply-templates select="current-group()" mode="identity"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each-group>
    </xsl:template>

  </xsl:stylesheet>

return xdmp:xslt-eval($xsl, $xml)

如果您想在< ins> 标记中获得最终PI,请按照Martin的建议,使用第二个for-each-group和group-end-by..以上可能就足够了.

Use a second for-each-group with group-ending-by as suggested by Martin if you like to get the end PI inside the <ins> tag. The above might be sufficient though.

HTH!

这篇关于使用XPATH在两个处理指令之间选择所有文本节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆