在 XSLT 中实现键值概念

2023-11-25

我正在研究 XSLT,我需要实现如下内容。 我的源 XML 示例如下所示。

<?xml version="1.0" encoding="ISO-8859-1"?>
    <catalog>
        <cd>
            <title>A</title>  
            <title>B</title>
            <title>C</title>  
        </cd>
    </catalog>

考虑那里有一些键值对列表。

    Key         Value
    A           Algebra
    B           Biology
    C           Chemistry
    D           Data Analysis
    ---         ---

    ----        ---

我需要编写一个 xslt,以便每次出现键“A”时都需要替换为适当的值。

我还需要提及同一 XSLT 中的键值对列表。 示例输出:

<Data>
    <Subject>Algebra</Subject>
    <Subject>Biology</Subject>
    <Subject>Chemistry</Subject>
 </Data>

任何人都可以帮我解决如何做到这一点。

谢谢。


一、简单的XSLT 1.0解决方案

这种转变:

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

 <my:codes>
   <code key="A" value="Algebra"/>
   <code key="B" value="Biology"/>
   <code key="C" value="Chemistry"/>
   <code key="D" value="Data Analysis"/>
 </my:codes>

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

 <xsl:template match=
  "title/text()[. = document('')/*/my:codes/*/@key]">

  <xsl:value-of select=
   "document('')/*/my:codes/*[@key=current()]/@value"/>
 </xsl:template>
</xsl:stylesheet>

当应用于提供的 XML 文档时:

<catalog>
    <cd>
        <title>A</title>
        <title>B</title>
        <title>C</title>
    </cd>
</catalog>

产生想要的正确结果:

<catalog>
   <cd>
      <title>Algebra</title>
      <title>Biology</title>
      <title>Chemistry</title>
   </cd>
</catalog>

解释:

这是将内联 XML 节点作为全局元素(的子元素)包含在内的标准方法xsl:stylesheet)属于(非空)命名空间,与 xsl 命名空间不同。


二.更高效的 XSLT 1.0 解决方案,使用密钥:

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

     <my:codes>
       <code key="A" value="Algebra"/>
       <code key="B" value="Biology"/>
       <code key="C" value="Chemistry"/>
       <code key="D" value="Data Analysis"/>
     </my:codes>

     <xsl:key name="kCodeByName" match="code" use="@key"/>

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

     <xsl:template match=
      "title/text()[. = document('')/*/my:codes/*/@key]">

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

      <xsl:for-each select="document('')">
          <xsl:value-of select=
           "key('kCodeByName', $vCur)/@value"/>
      </xsl:for-each>
     </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(上面)时,会产生相同的正确的、想要的结果:

<catalog>
   <cd>
      <title value="Algebra"/>
      <title value="Biology"/>
      <title value="Chemistry"/>
   </cd>
</catalog>

解释:

通过访问数据key()函数通常是次线性的——通常是 O(1) 并且比线性搜索要快得多(如果要搜索的节点数量很大,这一点很重要)。

通过索引访问一个文档的节点(xsl:key),如果包含要查找的节点的文档是当前文档,则可以处理另一个文档的节点。要从其他文档访问节点,需要保存其根(或感兴趣的节点)并引用变量。)


三. XSLT 2.0 解决方案:

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

 <xsl:variable name="vCodes">
  <codes>
   <code key="A" value="Algebra"/>
   <code key="B" value="Biology"/>
   <code key="C" value="Chemistry"/>
   <code key="D" value="Data Analysis"/>
  </codes>
 </xsl:variable>

 <xsl:key name="kCodeByName" match="code" use="string(@key)"/>

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

 <xsl:template match=
  "title/text()[key('kCodeByName', ., $vCodes)]">

  <xsl:sequence select=
   "key('kCodeByName', ., $vCodes)/@value"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(上面)时,会产生相同的正确的、想要的结果:

<catalog>
   <cd>
      <title value="Algebra"/>
      <title value="Biology"/>
      <title value="Chemistry"/>
   </cd>
</catalog>

解释:

几乎与高效的 XSLT 1.0 解决方案相同,但是:

  1. 在 XSLT 2.0 中,模板匹配模式can包含变量引用。

  2. 在 XSLT 2.0 中,不需要操作当前文档和索引文档的杂技——第三个参数key()功能是指定要使用其索引的树。

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

在 XSLT 中实现键值概念 的相关文章

随机推荐

  • Android 启用和禁用 GPS [重复]

    这个问题在这里已经有答案了 可能的重复 像 Tasker 一样以编程方式启用 GPS 我是一名初学者 Android 开发者 我想通过单击按钮来启用和禁用 GPS 而不运行此意图 intente in new Intent android
  • 如何使用Python中的套接字响应代理服务器中的“CONNECT”方法请求?

    我目前正在使用 httplib 编写代理服务器 当我尝试连接到 HTTPS 网站 例如 facebook 和 google 时 我的客户端向我发送 CONNECT 请求 如下所示 CONNECT www google co il 443 H
  • PHP 命名空间可以包含变量吗?

    PHP 命名空间可以包含变量吗 如果是这样 如何实现这一点 不可以 您可以在声明命名空间后设置变量 但变量将始终存在于全局范围内 它们永远不会绑定到名称空间 您可以从缺少任何名称解析描述的情况中推断出这一点 常见问题解答 有关命名空间您需要
  • 不使用 NewID() 的 SQL 上的随机数

    您好 我想生成一个唯一的随机数 而不使用以下语句 Convert int CHECKSUM NEWID 100000 AS ITEM 因为当我在 from 上使用连接子句时 它通过使用 NEWID 生成双寄存器 我使用 SQL Server
  • 如何在MySQL中进行级联更新?

    Let s look at this example database 正如我们所看到的 person 取决于城市 person city id 是外键 我不删除行 只是将它们设置为非活动状态 活动 0 将城市设置为非活动状态后 如何自动将
  • 默认导出类的新实例

    下面的代码片段每次导入时都会生成新实例吗 1st implementation class ConnectionManager export default new ConnectionManager 2nd implementation
  • google api javascript 登录用户的电子邮件

    有许多资源和堆栈溢出问题与我将要问的类似但不完全相同 我将在这里重新讨论一些解决方案并进行解释 我有一个已经登录 Google 的用户 我所说的登录是指手动登录并且存在 cookie 我的应用程序未登录 我只需要获取电子邮件地址 我见过 3
  • 哈希集的哈希码和等于[重复]

    这个问题在这里已经有答案了 请澄清我对 Hashset 的疑问 考虑下面的代码 class Person String name Person String n name n public String getName return nam
  • “写入输出时出现问题:字段引用太多:70185;最大值为 65536。您可以尝试使用 --multi-dex 选项。”构建Android项目时

    我遇到了这个错误 但没有找到错误消息 所以我想我应该分享我想出的解决方案 以防止其他面临问题的人重复我的工作 当编写一个新的 Android 库 apklib 以在 大型 应用程序中使用时 当我将新项目添加为依赖项时 我在 dexing 过
  • jquery 设置焦点于动态内容?

    在 jquery 中我附加了一个 li 元素到无序列表 我如何专注于新创建的 li li 如果我执行以下操作 ul append li li li
  • 使用 ios 7 视差效果移动图像

    我刚刚看到 Facebook 的新纸质应用程序 它可以根据视差效果使图像移动 因此 它将图像缩放到全屏 当您倾斜屏幕时 它会将图像滚动到您倾斜的一侧 我已经能够像苹果那样添加视差效果 但不能像 Facebook 那样添加视差效果 有谁知道他
  • 处理 Enum 类型时 CStr() 与 .ToString 的比较

    我 显然是错误的 假设Cstr something 相当于something ToString 我想将枚举类型作为字符串来获取 这似乎取决于我使用的转换方法 我要么获取该类型的索引enum或名称 Public Enum vehicleTyp
  • 如何在 findAll() 中获取数组结果 - Doctrine?

    我需要使用以下方法获取数据库中的所有记录作为数组findAll 在教义中 我的查询是这样的 result this gt getDoctrine gt getRepository CoreBundle Categories gt findA
  • 任务执行失败:':app:preDexDebug'

    我遇到了那个著名的 app preDexDebug 错误 首先 清理项目或重建项目可以正常工作 不会出现错误 在默认设置下 我将项目字节码版本设置为 1 7 并且在项目结构中的 SDK 位置下 JDK 位置似乎也是正确的 经过一段时间的研究
  • 由于信号导致命令失败:归档时分段错误:11

    我尝试存档我的应 用程序并收到此错误 由于信号导致命令失败 分段错误 11 当我构建它时 一切都很顺利 在真实设备上也是如此 归档时会发生这种情况 有什么想法如何解决吗 这是错误的一部分 0 swift 0x000000010f79f3ad
  • 如何在 Angular 中嵌套 routerLink

    我有一个 Angular 7 项目 我有路由器链接 a 标签 并且我已经嵌套了 a 两者都有的标签routerLink财产 我面临的问题是 内在 a 路线不起作用 a Comp1 a Navigate to comp2 Nested a a
  • Swift/iOS:如何在具有 AnyObject/Any 或指针的函数中使用 inout 参数

    我正在尝试编写一个函数 该函数接受变量指针和描述符 键并为变量设置新值 理想情况下 指针应该是对象或基元 但我也可以使用单独的函数 或附加参数 在我的代码中 我也使用该键从数据库中检索新值 但在下面的示例中 我使用虚拟值对其进行了简化 以便
  • 使用弱引用有什么好处?

    我的应用程序中存在一些内存泄漏 它们都源于一个特定的视图集群 我花了很多时间对其进行调整并尝试尽可能减少上下文传递 这让我相信集群中使用的位图是问题所在 所以我想对视图使用的位图的所有引用使用 Wea kReferences 我从未使用过
  • Android Studio:生成主 dex 列表时出错

    我试图从我的项目中完全删除 firebase 依赖项 但我已经设法完全搞砸了我的 gradle 我需要帮助才能使其再次工作 我需要有谷歌播放服务依赖项 因为我正在使用谷歌地图和地理围栏 这是我每次尝试重建项目时遇到的错误 java lang
  • 在 XSLT 中实现键值概念

    我正在研究 XSLT 我需要实现如下内容 我的源 XML 示例如下所示