使用 xslt 从 xpath 语句列表中注释 xml 实例

2023-12-08

给定一个 xpath 语句列表,我想编写一个样式表,它将运行一个 xml 文档并输出相同的文档,但在每个 xpath 语句中标识的节点之前插入注释。我们来举个例子。从包含 xpath 语句的 xml 实例开始:

<paths>
  <xpath location="/root/a" annotate="1"/>
  <xpath location="/root/a/b" annotate="2"/>
</paths>

给定输入:

<root>
  <a>
    <b>B</b>
  </a>
  <c>C</c>
</root>

它应该产生:

<root>
  <!-- 1 -->
  <a>
    <!-- 2 -->
    <b>B</b>
  </a>
  <c>C</c>
</root>

我最初的想法是拥有一个身份样式表,它需要file-list参数,调用document对其进行函数以获取 xpath 节点列表。然后它会根据该列表检查输入的每个节点,然后在找到一个时插入注释节点,但我预计随着 xpath 列表变大,这可能会非常低效(或者可能不会,告诉我。我正在使用撒克逊9)。

所以我的问题是:有没有一种有效的方法来做这样的事情?


假设 Saxon 9 PE 或 EE,还应该可以使用 XSLT 3.0 和xsl:evaluate如下:

<?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:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs math map mf"
    version="3.0">

    <xsl:output indent="yes"/>

    <xsl:param name="paths-url" as="xs:string" select="'paths1.xml'"/>
    <xsl:param name="paths-doc" as="document-node()" select="doc($paths-url)"/>

    <xsl:variable name="main-root" select="/"/>

    <xsl:variable 
        name="mapped-nodes">
        <map>
            <xsl:for-each select="$paths-doc/paths/xpath">
                <xsl:variable name="node" as="node()?" select="mf:evaluate(@location, $main-root)"/>
                <xsl:if test="$node">
                    <entry key="{generate-id($node)}">
                        <xsl:value-of select="@annotate"/>
                    </entry>
                </xsl:if>
            </xsl:for-each>
        </map>
    </xsl:variable>

    <xsl:key name="node-by-id" match="map/entry" use="@key"/>

    <xsl:function name="mf:evaluate" as="node()?">
        <xsl:param name="path" as="xs:string"/>
        <xsl:param name="context" as="node()"/>
        <xsl:evaluate xpath="$path" context-item="$context"></xsl:evaluate>
    </xsl:function>

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

    <xsl:template match="node()[key('node-by-id', generate-id(), $mapped-nodes)]">
        <xsl:comment select="key('node-by-id', generate-id(), $mapped-nodes)"/>
        <xsl:text>&#10;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="@* , node()"/>
        </xsl:copy>
    </xsl:template>


</xsl:stylesheet>

下面是最初发布的代码的编辑版本,它使用 XSLT 3.0 映射功能而不是临时文档来存储动态 XPath 评估找到的节点的生成 ID 与注释之间的关联:

<?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:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs math map mf"
    version="3.0">

    <xsl:param name="paths-url" as="xs:string" select="'paths1.xml'"/>
    <xsl:param name="paths-doc" as="document-node()" select="doc($paths-url)"/>

    <xsl:output indent="yes"/>

    <xsl:variable 
        name="mapped-nodes"
        as="map(xs:string, xs:string)"
        select="map:new(for $path in $paths-doc/paths/xpath, $node in mf:evaluate($path/@location, /) return map:entry(generate-id($node), string($path/@annotate)))"/>

    <xsl:function name="mf:evaluate" as="node()?">
        <xsl:param name="path" as="xs:string"/>
        <xsl:param name="context" as="node()"/>
        <xsl:evaluate xpath="$path" context-item="$context"></xsl:evaluate>
    </xsl:function>

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

    <xsl:template match="node()[map:contains($mapped-nodes, generate-id())]">
        <xsl:comment select="$mapped-nodes(generate-id())"/>
        <xsl:text>&#10;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="@* , node()"/>
        </xsl:copy>
    </xsl:template>


</xsl:stylesheet>

作为第一个样式表,它需要 Saxon 9.5 PE 或 EE 才能运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 xslt 从 xpath 语句列表中注释 xml 实例 的相关文章

随机推荐

  • 在 C# 中将像素数组转换为图像

    我有一个数组int我的 C 程序中存在像素 我想将其转换为图像 问题是我正在将程序的 Java 源代码转换为等效的 C 代码 在java中 该行读取将int像素数组显示到图像中 Image output createImage new Me
  • 无需内联汇编即可访问标志?

    我在 C 中有以下方法 它需要两个 16 位短整型 将两个整数相加 如果设置了进位标志 则结果加 1 对最终结果中的所有位取反 NOT 返回结果 short declspec naked getchecksum short s1 short
  • setWindowFlag(Qt::Dialog | Qt::WindowStaysOnTopHint) 在 Centos 上不起作用

    我正在打开一个表单窗口 并希望无论它是否聚焦 都始终将其保留在顶部 我正在使用此功能setWindowFlags Qt Dialog Qt WindowStaysOnTopHint QT 的它在 Mac 上工作正常 正如我所希望的 但是当我
  • 通过 TNS 连接到 Oracle 无法正常工作

    我有一个 Spring Boot 应用程序 当它以经典方式连接到 Oracle 实例时 它可以顺利运行 jdbc oracle thin
  • 您的安全设置阻止了应用程序使用过时或过期的 Java 版本运行

    问候 我遇到了一个 Java 错误 这实际上给我带来了一场噩梦 它说 应用被安全设置阻挡了 您的安全设置已阻止应用程序使用过时或过期的 Java 版本运行 Java 版本 1 7 25 推荐用于我的工作 我认为不是旧版本 我已经执行的解决方
  • 坚固耐用。 (vcovHC) 在 R 中用 texreg 显示

    我正在使用 plm 包进行一些回归 然后如果需要 我还可以获得异方差一致系数 以下是我运行的命令 library plm data Produc package plm zz lt plm log gsp log pcap log pc l
  • 从 Ensembl 基因 ID 转换为不同的标识符

    我继承了 Canis Lupus 狗 的 RNAseq 输出数据集 我有 Ensembl 格式的基因标识符 具体来说它们看起来像这样 ENSCAFT00000001452 3 我正在尝试使用 bioMaRt 将它们转换为更常见的 ID 需要
  • Oracle 中的递归

    我在预言机中有下表 Parent arg1 arg2 我想要关系父级的传递闭包 也就是我想要下表 Ancestor arg1 arg2 这在 Oracle 中怎么可能呢 我正在做以下事情 WITH Ancestor arg1 arg2 AS
  • 如何创建全局可访问的变量?

    我正在尝试创建一个可以在任何地方工作的变量 而不仅仅是在一个函数中 我该怎么做呢 我已经搜索了大约 1 个小时 但找不到它 我试过这个 noneTxt document innerHTML Nothing is playing functi
  • Azure 云服务:在网站(Web 角色)实例中进行缩放,在 iis 准备就绪之前接收请求

    描述 我在云服务中托管了一个 Web 角色 该服务是一个网站 我们通过自定义监控 辅助角色 来处理可预测的负载峰值 该监控将根据预测的负载配置文件定期缩小或缩小 那部分正在工作 Issue 通过监控安装网站的新实例后 我们刚刚遇到一个用户的
  • 计算 Google Maps API v3 中的折线(路线)和标记之间的距离

    有没有方便的方法来计算折线 由 Google Directions 生成的路线 和不在该折线上的标记之间的直接 最短 距离 我发现的唯一方法是循环遍历Polyline getPath 手动计算顶点来计算最短距离 但这似乎有点苛刻 var p
  • 如何将多个触摸操作附加到单个列表项?

    我正在使用以下列表布局items已关联的comments 的数量comments由右侧的框表示 目前 我正在使用onListItemClick处理程序启动另一个details view public class CustomListFrag
  • 如何使用 XSLT 2.0 和 REGEX(没有 \b 单词边界)在文本中查找单词?

    我正在尝试使用 REGEX 扫描一串单词并在 XSLT 2 0 样式表中查找特定单词 不区分大小写 的存在 我有一个单词列表 我希望迭代并确定它们是否存在于给定字符串中 我想匹配给定文本中任何位置的单词 但是我不想匹配within a wo
  • 使用“purrr”从列表列表中提取数据到自己的“data.frame”中

    代表性样本数据 列表列表 l lt list structure list a 1 54676469632688 b s c T d structure list id 5L label Utah link Asia Anadyr scor
  • 如何使用 SqlAlchemy 进行更新插入?

    我有一条记录 如果它不存在 我希望存在于数据库中 如果它已经存在 主键存在 我希望将字段更新到当前状态 这通常被称为upsert 以下不完整的代码片段演示了可行的方法 但它似乎过于笨拙 特别是如果有更多列 更好 最好的方法是什么 Base
  • 找不到 HTML 模板 [重复]

    这个问题在这里已经有答案了 当我尝试从模板文件夹加载注入的页面时 出现页面未找到错误 index html 页面是我启动服务器时默认启动的页面 它还包含 ng view 因此我可以注入 Angular 配置中指定的页面 这是我的项目结构 a
  • 如何在构建 Docker 映像时恢复 Postgres 转储?

    我试图避免在工作流程中接触共享开发数据库 为了使这更容易 我希望在我的磁盘上有 Docker 映像定义来满足我需要的模式 然而 我坚持制作一个 Dockerfile 该文件将创建一个已恢复转储的 Postgres 映像 我的问题是 在构建
  • CMakeLists.txt 可以依赖于函数解析的文件吗?

    我对 CMake 相当陌生 第一次从一个由许多子项目组成的较大项目开始 出于特殊原因 如下所述 出于好奇 我已经有了一组包含文件 其中包含有关每个 CMake 目标 lib 或 exe 所需的源文件的信息 目前 我更喜欢 重新 使用这些文件
  • 处理 Recyclerview 中的点击项

    我有一个卧式回收机view inside 垂直回收视图 我添加列表cardview inside 卧式回收机view 当点击主活动的项目时如何获取项目信息 谢谢 public class MainActivity extends AppCo
  • 使用 xslt 从 xpath 语句列表中注释 xml 实例

    给定一个 xpath 语句列表 我想编写一个样式表 它将运行一个 xml 文档并输出相同的文档 但在每个 xpath 语句中标识的节点之前插入注释 我们来举个例子 从包含 xpath 语句的 xml 实例开始