按 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 字母顺序对数据进行排序 的相关文章

随机推荐

  • 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