XSLT:通过递增属性和值生成多个对象

2024-03-10

我有一个如下所示的 xml,我想复制 n 次,同时递增其元素之一和属性之一。

XML 输入:

<Person position=1>
<name>John</name>
<number>1</number>
<number>1</number>
</Person>

我想要像下面这样的东西,增量的数量是一个变量。

XML 输出:

<Person position=1>
<name>John</name>
<number>1</number>
</Person>
<Person position=2>
<name>John</name>
<number>2</number>
</Person>
....
<Person position=n>
<name>John</name>
<number>n</number>
</Person>

Any clue


I. XSLT 1.0 解决方案:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pTimes" select="5"/>

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

 <xsl:template match="/*">
  <xsl:call-template name="applyNTimes">
    <xsl:with-param name="pTimes" select="$pTimes"/>
    <xsl:with-param name="pPosition" select="1"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="applyNTimes">
  <xsl:param name="pTimes" select="0"/>
  <xsl:param name="pPosition" select="1"/>

  <xsl:if test="$pTimes > 0">
   <xsl:apply-templates select="*">
    <xsl:with-param name="pPosition" select="$pPosition"/>
   </xsl:apply-templates>

   <xsl:call-template name="applyNTimes">
    <xsl:with-param name="pTimes" select="$pTimes -1"/>
    <xsl:with-param name="pPosition" select="$pPosition+1"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>

 <xsl:template match="Person">
  <xsl:param name="pPosition" select="1"/>

  <Person position="{$pPosition}">
   <xsl:apply-templates>
     <xsl:with-param name="pPosition" select="$pPosition"/>
   </xsl:apply-templates>
  </Person>
 </xsl:template>

 <xsl:template match="number">
  <xsl:param name="pPosition" select="1"/>

  <number><xsl:value-of select="$pPosition"/></number>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时:

<t>
    <Person position="1">
        <name>John</name>
        <number>1</number>
    </Person>
</t>

产生了想要的结果:

<Person position="1">
   <name>John</name>
   <number>1</number>
</Person>
<Person position="2">
   <name>John</name>
   <number>2</number>
</Person>
<Person position="3">
   <name>John</name>
   <number>3</number>
</Person>
<Person position="4">
   <name>John</name>
   <number>4</number>
</Person>
<Person position="5">
   <name>John</name>
   <number>5</number>
</Person>

二. XSLT 2.0 解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="xs"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pNumTimes" as="xs:integer" select="5"/>

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

 <xsl:template match="/">
   <xsl:variable name="vDoc" select="/"/>

     <xsl:for-each select="1 to $pNumTimes">
       <xsl:apply-templates select="$vDoc/*/*">
        <xsl:with-param name="pPosition" select="."/>
       </xsl:apply-templates>
     </xsl:for-each>
 </xsl:template>

 <xsl:template match="Person">
  <xsl:param name="pPosition" select="1"/>

  <Person position="{$pPosition}">
   <xsl:apply-templates>
     <xsl:with-param name="pPosition" select="$pPosition"/>
   </xsl:apply-templates>
  </Person>
 </xsl:template>

 <xsl:template match="number">
  <xsl:param name="pPosition" select="1"/>

  <number><xsl:value-of select="$pPosition"/></number>
 </xsl:template>
 </xsl:stylesheet>

三.使用 DVD 式递归来避免大 N 上的堆栈溢出 (XSLT 1.0)

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pTimes" select="5"/>

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

 <xsl:template match="/*">
  <xsl:call-template name="applyNTimes">
    <xsl:with-param name="pTimes" select="$pTimes"/>
    <xsl:with-param name="pPosition" select="1"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="applyNTimes">
  <xsl:param name="pTimes" select="0"/>
  <xsl:param name="pPosition" select="1"/>

  <xsl:if test="$pTimes > 0">
   <xsl:choose>
     <xsl:when test="$pTimes = 1">
           <xsl:apply-templates select="*">
            <xsl:with-param name="pPosition" select="$pPosition"/>
           </xsl:apply-templates>
     </xsl:when>
     <xsl:otherwise>
       <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>

       <xsl:call-template name="applyNTimes">
        <xsl:with-param name="pTimes" select="$vHalf"/>
        <xsl:with-param name="pPosition" select="$pPosition"/>
       </xsl:call-template>

       <xsl:call-template name="applyNTimes">
        <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
        <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
       </xsl:call-template>
     </xsl:otherwise>
   </xsl:choose>
  </xsl:if>
 </xsl:template>

 <xsl:template match="Person">
  <xsl:param name="pPosition" select="1"/>

  <Person position="{$pPosition}">
   <xsl:apply-templates>
     <xsl:with-param name="pPosition" select="$pPosition"/>
   </xsl:apply-templates>
  </Person>
 </xsl:template>

 <xsl:template match="number">
  <xsl:param name="pPosition" select="1"/>

  <number><xsl:value-of select="$pPosition"/></number>
 </xsl:template>
</xsl:stylesheet>

深度递归的问题是调用堆栈耗尽导致堆栈溢出。在不同的系统上,这种情况会在不同的嵌套级别上发生,但这通常发生在 N = 1000 左右。

上述改造实际上不存在这样的问题。 DVC 的最大递归深度为 log2(N),这意味着如果我们需要重复该操作 1000000 (1M) 次,则最大递归深度仅为 19。

四.最后,如何完全避免递归(XSLT 1.0)

对于已知的、不太大的 N,以下非递归技术效果很好:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pTimes" select="5"/>

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

 <xsl:template match="/*">
  <xsl:call-template name="applyNTimes">
    <xsl:with-param name="pTimes" select="$pTimes"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="applyNTimes">
  <xsl:param name="pTimes" select="0"/>

 <xsl:variable name="vCurrent" select="."/>

  <xsl:if test="$pTimes > 0">
   <xsl:for-each select=
     "document('')//node() | document('')//@* | document('')//namespace::*">
    <xsl:if test="not( position() > $pTimes )">
        <xsl:apply-templates select="$vCurrent/*">
         <xsl:with-param name="pPosition" select="position()"/>
        </xsl:apply-templates>
    </xsl:if>
   </xsl:for-each>
  </xsl:if>
 </xsl:template>

 <xsl:template match="Person">
  <xsl:param name="pPosition" select="1"/>

  <Person position="{$pPosition}">
   <xsl:apply-templates>
     <xsl:with-param name="pPosition" select="$pPosition"/>
   </xsl:apply-templates>
  </Person>
 </xsl:template>

 <xsl:template match="number">
  <xsl:param name="pPosition" select="1"/>

  <number><xsl:value-of select="$pPosition"/></number>
 </xsl:template>
</xsl:stylesheet>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

XSLT:通过递增属性和值生成多个对象 的相关文章

  • 表、TR各2个循环、PHP、HTML

    我有一个 html 表 我使用一些循环来获取一些数据 该数据以这种方式显示 tr td Data td tr next loop 但我不希望它每 2 个甚至 3 个循环关闭表行 tr 所以数据可能如下所示 tr td Data td td
  • 基于已知 XSL 对未知 XML 进行逆向工程

    Solved 在遵循 Matti 的建议后 我删除了自定义函数 一切都很好 原帖 截至今天 我还是 XSLT 的新手 所以我确信这对你们中的许多人来说是理所当然的 无论如何 我的任务是使用第三方供应商提供的数据为我公司的网站创建一个小部件
  • 遍历多行字符串

    我得到一些数据 def data some useless text n even more n finally interesting text 我怎样才能得到其中 有趣的部分 所以基本上所有行都不是以 开头的 Groovy 的一种选择是
  • 在另一个数组的每隔一个元素之后插入一个数组中的元素(一次一个)(不均匀拉链)

    合并两个数组的优雅方法是什么 使得生成的数组具有第一个数组中的两个项目 后跟第二个数组中的单个项目 以这种方式重复 array1 A1 A2 A3 A4 A5 potentially longer array2 B1 B2 B3 B4 B5
  • 使用 XSLT(即 XML Transformer)时防止 DTD 下载

    我必须在 Java 中处理具有 DTD 和 XSLT 的 XML 文件 DTD 确实是必要的 因为它包含我使用的实体的定义 旁白 是的 将实体用于可以使用 unicode 的东西是一个坏主意 当我运行转换时 它每次都会从外部源下载 DTD
  • 如何对 int[] 数组求和[重复]

    这个问题在这里已经有答案了 给定一个数组A of 10 ints 初始化一个名为的局部变量sum并使用循环查找数组中所有数字的总和A 这是我提交的答案 sum 0 while A lt 10 sum sum A 我在这个问题上没有得到任何分
  • 如何从头开始重复C程序并清理屏幕和第一个输入值?

    我是编程新手 我写了一个简单的程序 我想一次又一次地重复该程序 并且只有当用户想要退出时它才能退出 这是我的程序 include
  • for 和 while 循环中没有循环条件

    while cond fine for cond fine 但是当我删除条件部分时 while syntax compilation error for Infinite loop 这些循环内部是如何实现的 或者 编译器 解析器 如何知道中
  • 过早退出 Qualtrics 中的循环和合并块

    我目前正在进行一项 Qualtrics 调查 受访者必须解决一长串字谜问题 然后回答一些人口统计问题 为了使变位词部分更容易 我使用了循环和合并块 第一个字段是要解决的变位词 第二个字段是变位词的解决方案 因此调查可以根据受访者的答案来检查
  • 在 Clojure 中退出 Recur 循环

    我想跳出下面的循环 并在第 10 行计算结果为 true 时返回最佳最小移动 我查看了 print 语句的输出 当第 10 行的计算结果为 true 时 它 找到了我正在查找的数据 但仍然重复出现 在 Clojure 中 有没有办法在语句计
  • 在 while 循环之外使用变量(作用域)

    关于 PHP 范围的小问题 我似乎无法在 while 循环之外调用变量 report 我尝试过各种事情 包括return 这不起作用 这里唯一起作用的两个函数是如果我echo变量 report在循环内 或者如果我print它 我不想这样做
  • XSLT;将转义文本解析为节点集并提取子元素

    我一整天都在与这个问题作斗争 几乎束手无策 我有一个 XML 文件 其中数据的某些部分存储为转义文本 但它们本身是格式良好的 XML 我想将此文本节点中的整个层次结构转换为节点集并提取其中的数据 我能想到的变量和函数的组合都不起作用 我期望
  • 带 If 的嵌套 For 循环的时间复杂度

    void f int n for int i 1 i lt n i if i int sqrt n 0 for int k 0 k lt pow i 3 k do something 我的思考过程 执行if语句的次数 sum i 1 to
  • Python:使类可迭代

    我继承了一个包含许多大型类的项目 这些类仅由类对象 整数 字符串等 组成 我希望能够检查属性是否存在 而无需手动定义属性列表 是否可以制作一条蟒蛇classiterable 本身使用标准语法 也就是说 我希望能够使用迭代所有类的属性for
  • 如何去除 XSL 中字符的重音符号?

    我一直在寻找 但找不到相当于字符 规范化空间 的 XSL 函数 也就是说 我的内容带有重音 UNICODE 字符 这很好 但是从该内容中 我正在创建一个文件名 但我不想要这些重音 那么 是否有一些我忽略的东西 或者没有正确地谷歌搜索来轻松处
  • 如何使用额外标记输出 wp_list_categories

    我目前正在使用下面的脚本在无序列表中输出我的所有 WordPress 类别 如何获得带有额外标记的输出 ul ul 例如 ul li Category 1 rsaquo li li Category 2 rsaquo li ul 代替 ul
  • 如何在函数执行后停止 tkinter?

    我在停止 提要 时遇到问题 cancel 参数似乎对 after 方法没有任何影响 尽管 feed stop 被打印到控制台 我正在尝试使用一个按钮来启动源 另一个按钮来停止源 from Tkinter import Tk Button i
  • 在matlab中不使用for循环检查数组中的成员资格

    我想简化这段代码 使其无需 for 循环即可工作 for i 1 N for j 1 N if ismember j A PID i i TFP i j PID i i end end end 其中A是一个包含一些标签的矩阵 我之前存储的T
  • 如何制作一个 bash 脚本来同时创建 40 个程序实例?

    我是新来的bash and Linux 我编写了一个程序 我想创建多个同时实例 现在 我通过打开 10 个新终端 然后运行该程序 10 次 我运行的命令是php home calculatedata php 使用 bash 脚本执行此操作的
  • Snowflake 中的动态 SQL

    当我在雪花中运行动态 SQL 时 遇到以下错误 未完成对 SQL MAIN 的分配 因为值超出了变量的大小限制 它的大小是263 限制为 256 内部存储大小以字节为单位 这是代码 SET v G 1 SET v G1 v G VARCHA

随机推荐

  • 如何在没有键的情况下实现 SQL 外连接的 pandas 等价

    在 SQL 中 您可以在没有键的情况下连接两个表 以便两个表的所有记录相互合并 如果pandas concat or pandas merge 或者其他一些 pandas 语法支持这一点 它可以帮助我解决我试图解决的问题的一步 我在帮助文档
  • 当属性名称与类名称匹配时该怎么办

    在我们的 C 代码中 我们有一个名为 Project 的类 我们的 BusinessObject 基类 所有业务对象都继承自该类 定义了一个属性 public Project Project get set 只要我们留在 C 代码库中 这通
  • 您无法切换到 Apps 脚本创建的 Cloud Platform 项目 - 将 Apps 脚本文件与 Cloud Project 关联

    我正在尝试将新的应用脚本附加到我的 Google Cloud 项目 在 Apps 脚本代码编辑器中 我尝试使用菜单连接到云平台项目 资源 gt 云平台项目 但是当我添加项目编号时 我收到错误消息 您无法切换到 Apps 脚本创建的 Clou
  • 在 R 中访问共享点文件夹

    我目前正在尝试访问 R 中的共享点文件夹 我阅读了多篇解决该问题的文章 但所有建议的解决方案似乎都不适用于我的情况 我首先尝试使用 httr 包上传单个 txt 文件 如下所示 URL lt
  • 接受字节数组,vb6 到 C# 互操作

    我正在做一个将 vb6 与加密包装器通信的应用程序 到目前为止 net 和互操作部分一切正常 完全正常工作 当我的客户正在测试它时 我有一个简单的问题 ComVisible true public SomeObjectComVisible
  • 重新加载网页后如何保留滚动位置? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 document ready function addmedic click function ses
  • XMPPFramework - 如何注册新用户帐户

    我正在尝试使用 XMPPFramework 连接到 Openfire 服务器并创建一个新的用户帐户 如果我已经以其他用户身份登录 此代码将创建一个新的用户帐户 NSXMLElement query NSXMLElement elementW
  • 手动将 UITabBar 添加到 UITableViewController

    我有一个标准应用程序 带有管理多个 UITableViewController 类的导航控制器 我想将 UITabBar 添加到根视图 UITableViewController 来管理过滤 UITableView 中显示的对象的选择 我不
  • 如何刷新表中的单行?

    是否可以刷新a的单行vaadin table成分 到目前为止 如果表行编辑完成 我只需刷新整个表 table refreshRowCache 但这可能会导致稍后的大型表出现性能问题 那么 如何刷新单行呢 我在 Vaadin 论坛上发现了这个
  • Array.delete(object) 从数据库中删除?

    所以我试图获取一系列不包含 post 的帖子 令我惊讶的是 下面的代码导致 post 被从数据库中删除 post Post find 2 posts Post where text gt title posts delete post 为什
  • Android onNewIntent() 通知未正确执行

    我有一个用于通知的广播接收器 我的应用程序是一个 webkit 我希望当用户单击通知时打开我的应用程序并定向到某个 URL 一切似乎都工作正常 但我现在遇到了问题 onNewIntent 如果用户上次通过按主页按钮退出应用程序 则调用此方法
  • 相机标定opencv

    你好 我正在做一个项目来进行图像 3D 重建 我正在校准相机的阶段 这需要很长时间才能完成 但是当我编译代码并在相机前显示棋盘时 它会直接进入未处理的异常错误 当图片不在框架中时 一旦进入框架就没有错误 出现未处理的错误我不知道为什么 我问
  • ActiveJob Deliver_later 不发送

    我有以下方法 UserMailer comment alert comment user type deliver later 奇怪的是 它与参数一起出现deliver now在 Rails 日志中 ActiveJob Enqueued A
  • 如何在 Kotlin DSL 中有条件地接受 Gradle 构建扫描插件服务条款?

    这基本上延伸了这个问题 https stackoverflow com q 52636622 1127485使用 Kotlin DSL 而不是 Groovy DSL 如何Groovy DSL 解决方案 https stackoverflow
  • 将 ASP.net Core 2.0 部署到 Azure

    我已通过以下步骤将 ASP net Core 1 1 应用程序升级到 ASP net Core 2 0 将目标框架更改为2 0 升级所有 Nuget 包 现在 我从 git 进行的自动部署运行并显示成功 但应用程序未运行 我收到以下错误 H
  • R,dplyr - group_by()和arrange()的组合不会产生预期的结果?

    使用 dplyr 函数时group by 紧接着arrange 我希望得到数据帧已排序的输出within我所说的组group by 我对文档的阅读是 这种组合应该产生这样的结果 但是当我尝试时 这不是我得到的 并且谷歌搜索并没有表明其他人遇
  • 将 Boost 适配器与 C++11 lambda 结合使用

    我尝试编译这段代码 include
  • 虚拟继承混乱

    我正在阅读有关继承的内容 并且有一个主要问题 我几个小时都无法解决 给定一个类Bar是一个类virtual功能 class Bar virtual void Cook 两者有什么不同 class Foo public Bar virtual
  • CollectionView 内的按钮不可点击

    我在集合视图的自定义单元格中有一个按钮 集合视图位于滚动视图上 由于某种原因 我无法单击该按钮 我已检查我的所有元素是否都启用了用户交互 Here is my layout of the collection I ve hidden som
  • XSLT:通过递增属性和值生成多个对象

    我有一个如下所示的 xml 我想复制 n 次 同时递增其元素之一和属性之一 XML 输入