按 xml 字母顺序对数据进行排序

2024-02-17

输入 XML:

<?xml version="1.0" encoding="utf-8" ?>
<infoset>
  <info>
    <title>Bill</title>
    <group>
      <code>state</code>
    </group>
  </info>
  <info>
    <title>Auto</title>
    <group>
      <code>state</code>
    </group>
  </info>
  <info>
    <title>Auto2</title>
  </info>
  <info>
    <title>Auto3</title>
  </info>
  <info>
    <title>Auto5</title>
  </info>
  <info>
    <title>Certificate</title>
    <group>
      <code>Auto4</code>
    </group>
  </info>
  </infoset>

预期输出:

A

Auto2
Auto3
Auto4
   Certificate
Auto5

S
state
   Auto
   Bill

我需要按字母顺序排列标题和代码。如果信息有组,则磁贴应位于该组下。我正在使用 Visual Studio2010 、 xslt1.0 处理器和 xml 编辑器。


XSLT 中的排序非常简单。您实际上真正需要知道的是如何对项目进行“分组”。正如 Michael Kay 所评论的,这在 XSLT 2.0 中比在 XSLT 1.0 中容易得多。在 XSLT 1.0 中,您倾向于使用 Muenchian 分组方法,当您第一次看到它时,它会显得令人困惑,但通常是最有效的方法。

从输出的外观来看,您正在进行两次分组。首先,按第一个字母,然后按任一字母组/代码(如果存在),或者title.

Muenchian 分组通过定义一个键来工作,以便快速查找“组”中的所有项目。对于其中的第一个字母组/代码 or title,你可以像这样定义它

<xsl:key name="letter" match="info" use="substring(concat(group/code, title), 1, 1)"/>

(注意:这区分大小写,因此如果您可以混合使用小写和大写起始字母,则可能需要使用“翻译”功能)。

If 组/代码存在,它将使用该的第一个字母,否则它将选取该的第一个字母title.

For the 组/代码 or title本身,关键如下

<xsl:key name="info" match="info" use="title[not(../group)]|group/code"/>

因此,它仅使用不存在“group”元素的“title”元素。

要获得第一个分组的不同首字母,请选择所有info元素并检查它们是否是给定字母的键中的第一个元素。这是这样完成的

<xsl:apply-templates 
     select="info
             [generate-id() 
              = generate-id(key('letter', substring(concat(group/code, title), 1, 1))[1])]" 
     mode="letter">
  <xsl:sort select="substring(concat(group/code, title), 1, 1)" />
</xsl:apply-templates>

此处使用“模式”是因为最终的 XSLT 必须与模板匹配info.

在匹配模板中,按以下任一分组代码/组 or title然后你可以这样做

<xsl:apply-templates 
     select="key('letter', $letter)
            [generate-id() = generate-id(key('info', title[not(../group)]|group/code)[1])]">
  <xsl:sort select="title[not(../group)]|group/code" />
</xsl:apply-templates>

最后,要输出最终组中的所有元素,您只需再次使用该键即可

<xsl:apply-templates select="key('info', $value)[group/code=$value]/title">

这是完整的 XSLT。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes"/>

  <xsl:key name="letter" match="info" use="substring(concat(group/code, title), 1, 1)"/>
  <xsl:key name="info" match="info" use="title[not(../group)]|group/code"/>

  <xsl:template match="/*">
    <xsl:apply-templates select="info[generate-id() = generate-id(key('letter', substring(concat(group/code, title), 1, 1))[1])]" mode="letter">
      <xsl:sort select="substring(concat(group/code, title), 1, 1)" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="info" mode="letter">
    <xsl:variable name="letter" select="substring(concat(group/code, title), 1, 1)" />
    <xsl:value-of select="concat($letter, '&#10;')" />
    <xsl:apply-templates select="key('letter', $letter)[generate-id() = generate-id(key('info', title[not(../group)]|group/code)[1])]">
      <xsl:sort select="title[not(../group)]|group/code" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="info">
    <xsl:variable name="value" select="title[not(../group)]|group/code" />
    <xsl:value-of select="concat($value, '&#10;')" />
    <xsl:apply-templates select="key('info', $value)[group/code=$value]/title">
      <xsl:sort select="." />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="title">
    <xsl:value-of select="concat('   ', ., '&#10;')" />
  </xsl:template>
</xsl:stylesheet>

当应用于您的 XML 时,输出如下

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

按 xml 字母顺序对数据进行排序 的相关文章

  • 在 XSL 转换期间维护 XML 注释

    XML
  • 元素的前同级元素和
    元素的后同级元素​​移动到
    元素下

    我们正在尝试将任何标签移至section元素 如果标签是前同级元素section和以下兄弟姐妹section元素 请看下面的例子并提出建议 提前致谢 input
  • 如何转义 xsl:param 中的分号?

    我正在 Visual Studio 中编写 XSL 转换 据报告 下面的分号是一个 意外的标记
  • 如何将 XML 转换为字符串而不使用 .NET 中的文件?

    假设我有两个字符串 一种是XML数据 另一个是XSL数据 如果您必须知道的话 xml 和 xsl 数据存储在数据库列中 如何在 C 中转换 XML 而不先将 xml 和 xsl 保存为文件 我也希望输出是一个字符串 来自转换的 HTML 看
  • XSLT 和临时文档

    我正在尝试处理一个 xml 文件 该文件有几个不同的状态组 例如
  • 在 Chrome 中调试 XSLT

    我在 Chrome 中进行 XSL 翻译时遇到问题 我想知道是否有任何工具可以让我逐步浏览样式表以查看问题出在哪里 Use 节点测试 http dpawson co uk xsl sect2 nodetest html检查 XPath 查询
  • 使用 XSLT 转换 XML 并保留 Unicode 字符

    我的 XSLT 转换已经成功了几个月 直到我遇到带有 Unicode 字符 很可能是表情符号 的 XML 文件 我需要保留 Unicode 但 XSLT 正在将其转换为 HTML 实体 我认为将编码设置为 UTF 8 可以解决我的问题 但我
  • 使用版本控制时处理多台计算机上的 web.config 差异

    我确信每个人都必须处理这些情况 我们检查我们的源代码控制解决方案 每台开发机器都有自己的资源用于调试 构建和测试 最常见的是 网络服务器 IIS 数据库 SQL Web服务器很容易处理 每个开发机器都会有自己的proj user文件来指定不
  • 在同一节点上匹配不同配置的模板

    我问了我的整个问题这里关于堆栈溢出 https stackoverflow com questions 64966059 nesting xsl templates and referring multiple templates to t
  • XSD 到 XForms 以及 XForms 到 XSD 转换

    目前我正在努力解决两个问题 我从外部服务器接收到一个 XSD 文件 并且基于该文件我必须生成 XForm 通常 XSD 文件会导入许多其他 XSD 文件等等 我正在使用 XForm 构建器编写 GUI 当用户构建他的自定义 XForm 时
  • 重新审视混合字符串值的字母数字排序

    请注意 我之前提出了一个非常相似的问题 但要求已发生变化 对混合字符串值进行字母数字排序 https stackoverflow com questions 3842719 alphanumeric sort on mixed string
  • 由于命名空间“xmlns”,无法使用 XSLT 转换 XML

    我一直在尝试使用 XSLT 转换 XML 文件 但由于一些问题 即 xmlns 它没有转换 我 一辈子都找不到问题所在 XML 文件
  • XSLT 是 Web 框架的好选择吗?

    我一直认为 XML 以及之前的 SGML 数据是魔鬼的格式 我是旧数据库和平面文件学校的 尽管如此 我们正在开发一款商用网络产品 其框架基于在链中翻译 转换 XML 数据 当我们面试职位以及与潜在客户交谈时 他们喜欢它将做什么的概念 但厌倦
  • 将某些子节点下移到新的孙子级别

    我发现了有关将节点向上移动到父节点的其他问题 但我缺少将它们向下移动到新创建的节点的技巧 Given
  • 带有 xml 样式表的 XslTransform

    好像大家都说如果使用XslTransform 会先调用Load加载样式表 然后调用Transform进行转换 但是我有以下 XML 文件 我是否应该先加载xml 找到样式表节点 然后调用Load来加载样式表 或者还有其他方法吗 是处理指令
  • 使用 XSLT 向上移动节点

    我已经做了很多搜索 但我无法弄清楚如何准确地使用模板 我的输入数据称为 DEBTORS xml
  • 间接变量/参数引用(另一个属性/另一个变量中的名称)

    是否可以使用 XSL 访问名称存储在另一个变量 或参数 中的变量 或参数 如果没有 为什么 我是 xsl 的新手 来自其他语言 可以使用此功能 例如 bash ant 也许我在寻找这个问题的答案时就错了 但既然我在SO上没有找到它 我想应该
  • 如何让 XSLT 在 Java 中返回 UTF-8

    我正在尝试让我的 XSL 脚本使用 UTF 8 编码 像 和希腊字符这样的字符就像垃圾一样出现 让它工作的唯一方法是将结果写入文件 如果我将它写入输出流 它只会返回垃圾 System out 有效 但这可能是因为它被重定向到文件 结果需要从
  • xslt 匹配过滤结果集的前 x 项

    对 xslt 很陌生 所以如果这是一个基本问题 请原谅我 我无法在 SO 上或通过 Google 搜索找到答案 我想要做的是返回一组经过过滤的节点 然后对该组中的前 1 或 2 个项目进行模板匹配 然后另一个模板与其余项目匹配 但是如果没有
  • XPath - 测试是否至少有一个节点具有给定值

    给定以下 XML

随机推荐

  • Qt 全局样式表加载?

    如何使用 Qt 全局加载样式表 qss 样式资源 我正在努力让事情变得比以下更有效率 middleIntText gt setStyleSheet QLineEdit border 1px solid gray border radius
  • 是否可以将 LIMIT 与子查询结果一起使用?

    当需要有序集的最后几行时 通常会创建派生表并重新排序 例如 返回自动递增表的最后 3 个元素id SELECT FROM SELECT FROM table ORDER BY id DESC LIMIT 3 t ORDER BY t id
  • \n 在 Sklabel SpriteKit 中不起作用

    我在我的游戏中使用了以下代码 问题是我无法像使用 CCLabelTTF 那样在 spritekit 中制作多行标签 有人可以帮助我吗 另外我无法在我的代码中使用 t 或 n 感谢您的提前回复 SKLabelNode winner SKLab
  • C++11 std::threads 并等待线程完成

    我有一个计时器对象向量 每个计时器对象都会启动一个模拟生长期的 std thread 我正在使用命令模式 发生的情况是每个计时器都被一个接一个地执行 但我真正想要的是一个被执行 然后一旦完成 下一个 一旦完成下一个 同时不干扰主程序的执行
  • 工具提示内的图像tiptip

    我需要在具有悬停效果的工具提示中插入图像 tel view tipTip defaultPosition top delay 400 fadeIn 400 keepAlive true activation click HTML img s
  • 多个神经网络各有一个输出还是一个有多个输出?

    我想将输入分类为三种可能性之一 使用 3 个网络 每个网络有一个输出 还是 1 个网络 每个网络有 3 个输出 更好 即 3 个网络输出0 or 1或 1 个输出长度为 3 的单热向量的网络 1 0 0 答案是否会根据输入数据分类的复杂程度
  • 无法在 Keras 中复制 matconvnet CNN 架构

    我在 matconvnet 中有以下卷积神经网络架构 我用它来训练我自己的数据 function net cnn mnist init varargin CNN MNIST LENET Initialize a CNN similar fo
  • 在 lambda 中使用 aws-sdk 吗? (AWS.ApiGatewayManagementApi 不是 Response 的构造函数)

    我正在尝试在 lambda 中使用 aws sdk 但我似乎无法弄清楚 var AWS require aws sdk AWS config update var DDB new AWS DynamoDB apiVersion 2012 1
  • 使用 Bootstrap 3 垂直居中元素

    我想将 设计 标签和 21nov 垂直居中 div class row div class col xs 6 col xs offset 1 a href job 52 span class jobtitle designer span a
  • 调整 div 大小以适应最大高度的内容

    我有一个包含动态内容的 div 当内容加载到 div 中时 我希望调整 div 大小以适应内容 但我希望此调整大小具有最大高度 如果内容需要超过这个最大高度 我希望有一个滚动条 我已经搜索过这里的问题 但无法找到我要找的东西 除了提问者回答
  • 带有子目录的 CMake

    我正在尝试设置我的项目以使用 CMake 正确编译 我的目录如下所示 root bin Where I want to build CMake from using cmake build include database database
  • Scala 抽象类型表示子类的类型

    我正在寻找一种方法来定义返回类型 T 的方法 其中 T 子类的类型 我知道我可以使用抽象类型来做到这一点 但不喜欢必须为每个子类重新定义 T 的开销 一些示例代码 object Helper def help A lt MyClass cl
  • Jquery Datepicker 更改月份后触发(月份渲染后)

    我想强调一下本月的一些日子 我可以在第一个月执行此操作 但不能在单击 下个月 或 上个月 后的新月份执行此操作 我尝试使用 onChangeMonthYear 事件 但这在新的 或上一个 月份呈现之前执行 有任何想法吗 也许你最好的选择是b
  • Windbg:psscor4 不起作用

    我搜索并尝试了很多东西 但无法让 psscor4 正常工作 当我调用 threads 我总是得到 请求ThreadStore失败 我检查的内容如下 我有一个为 X86 平台编译的 NET 4 应用程序 我使用的是Windbg版本6 2 92
  • 两组之间均匀分布的数字 (Vectorize LINSPACE) - MATLAB

    如何定义矩阵M根据M a b a 5 b from a to b分 5 步 当a and b是向量或集合 更具体地说 每一行i in M第一个值应该等于a i 和最后的值b i 其间有 5 个相等的步骤 例如 如果我有 a 0 b 10 0
  • 如何将两个 PDF 页面拼接在一起成为一张大页面?

    我有两张 36 x 48 海报 LaTeX 我想将其附加到一张 72 x 48 海报中 垂直堆叠 浏览 SO 和 GS 文档 我没有任何线索 我不是 CLI 向导 我怎样才能做到这一点 此外 该过程不应有损地压缩光栅图像 因为这将以 240
  • switch 似乎比 if 慢

    我很好奇速度switch 相信它 非常 快 但我有一个测试用例 似乎表明单个开关的速度大约与 4 一样快if测试 当我预期 没有充分的理由 它会像 1 次测试一样快 这是我写的两个方法来比较switch with if public sta
  • 挑选一个删除文件的提交

    我需要合并几个存储库 每个存储库都是从TFS http en wikipedia org wiki Team Foundation Server 合而为一 为此 我使用 gitcherry pick 命令 该命令适用于某些提交 但不适用于其
  • 缺少 Google 地图 API V2 google-play-services_lib.jar

    I just imported an example of the google map api V2 for android to test It s missing the google play services lib jar I
  • 按 xml 字母顺序对数据进行排序

    输入 XML