XSLT 2.0通过第一次出现元素来分裂current-group

如何解决XSLT 2.0通过第一次出现元素来分裂current-group

使用XSLT 2.0,假设您有current-group() = {A,X,B,B,X} ,其中 A,B, X 是元素。 有效且清晰的方法是在第一次出现 B 时将其拆分以得到两个序列 S1 S2 S1 = {A,X} S2 = {B,B,X} ?是否可以使用 xsl:for-each-group 构造来完成此操作?

编辑:current-group()的元素不保证是兄弟姐妹,但可以保证按文档顺序排列。


首次尝试:将 xsl:for-each-group group-starting-with

一起使用
<xsl:for-each-group select="current-group()" group-starting-with="B[1]">
  <xsl:choose>
    <xsl:when test="position() = 1">
      <!-- S1 := current-group() -->
    </xsl:when>
    <xsl:otherwise>
      <!-- S2 := current-group() -->
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each-group>

如果在current-group()的第一个 B 中没有前面的 B 兄弟,则此方法有效。 我本以为位置谓词[1]的范围将是select子句,因为current-group()[self::B][1]返回正确的 B 。我很想知道为什么它不能这样作用范围。

XML

<root>
  <A>A1</A>
  <B>B1-1</B>
  <B>B1-2</B>
  <A>A2</A>
  <B>B2-1</B>
  <B>B2-2</B>
</root>

XSLT

<xsl:template match="root">
  <xsl:copy>
    <xsl:for-each-group select="*" group-starting-with="A">
      <xsl:for-each-group select="current-group()" group-starting-with="B[1]">
        <xsl:choose>
          <xsl:when test="position() = 1">
            <S1><xsl:copy-of select="current-group()" /></S1>
          </xsl:when>
          <xsl:otherwise>
            <S2><xsl:copy-of select="current-group()" /></S2>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each-group>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

结果

<root>
  <S1>
    <A>A1</A>
  </S1>
  <S2>
    <B>B1-1</B>
    <B>B1-2</B>
  </S2>
  <S1>
    <A>A2</A>
    <B>B2-1</B>
    <B>B2-2</B>
  </S1>
</root>

如您所见,第一组已正确拆分,但第二组未正确拆分。但是,如果将current-group()包裹在一个父项中,然后将其传递给select子句,这将起作用,但这似乎效率不高。

解决方法

functx库定义了一个函数functx:index-of-nodehttp://www.xsltfunctions.com/xsl/functx_index-of-node.html):

<xsl:function name="functx:index-of-node" as="xs:integer*"
              xmlns:functx="http://www.functx.com">
  <xsl:param name="nodes" as="node()*"/>
  <xsl:param name="nodeToFind" as="node()"/>

  <xsl:sequence select="
  for $seq in (1 to count($nodes))
  return $seq[$nodes[$seq] is $nodeToFind]
 "/>

</xsl:function>

这将减少您的第二种方法

<xsl:template match="root">
  <xsl:copy>
    <xsl:for-each-group select="*" group-starting-with="A">
        <xsl:variable name="pos" select="functx:index-of-node(current-group(),(current-group()[self::B])[1])"/>
        <S1>
            <xsl:copy-of select="current-group()[position() lt $pos]"/>
        </S1>
        <S2>
            <xsl:copy-of select="current-group()[position() ge $pos]"/>
        </S2>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

在具有扩展功能saxon:items-beforesaxon:items-fromsyntax extension for anonymous functions的Saxon 10 PE或EE的“新”“ XSLT 4”世界中,您可以将其编写为

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:saxon="http://saxon.sf.net/"
    exclude-result-prefixes="#all" version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:output indent="yes"/>

    <xsl:template match="root">
        <xsl:copy>
            <xsl:for-each-group select="*" group-starting-with="A">
                <S1>
                    <xsl:apply-templates
                        select="saxon:items-before(current-group(),.{ . instance of element(B) })"/>
                </S1>
                <S2>
                    <xsl:apply-templates
                        select="saxon:items-from(current-group(),.{ . instance of element(B) })"/>
                </S2>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-