【问题标题】:XSLT for an XML document with arbitrary tags用于带有任意标签的 XML 文档的 XSLT
【发布时间】:2013-10-14 14:55:24
【问题描述】:

为了澄清标题,我有一个如下所示的 XML 文档:

<group>
  <starter>Start</starter>
  <backup1>Backup1</backup1>
</group>
<group>
  <starter>Another starter</starter>
  <backup1>Backup1</backup1>
  <backup2>Backup2</backup2>
  <backup3>Backup3</backup3>
  <reserve>Reserve</reserve>
</group>

所以每个组可以有任意数量的&lt;backupN&gt; 标签。我需要确保我的 XSLT 抓取了所有这些并将它们重命名为“backup_n”。通常,我的 XSLT 会应用符合以下内容的内容:

<xsl:for-each select="group/backup">

并围绕该 xpath 选择进行循环。这显然行不通,因为即使只有 1 个备份,它仍然被命名为 &lt;backup1&gt; 并且还可以有任意数量的 &lt;backupN&gt; 标签。

像这样循环任意标签的最佳方法是什么?我正在使用 XSLT 1.0,所以不能真正使用任何 XSLT 2.0 的优点。

【问题讨论】:

  • 您有一个包含错误命名元素的文档(&lt;backup1&gt; 到 &lt;backupN&gt;)并且想要将其转换为另一个包含错误命名元素的文档(&lt;backup_1&gt; 到 &lt;backup_N&gt;)?如果您有能力,请将其更改为 &lt;backup num="1"&gt; ... &lt;backup num="N"&gt;,正是出于让您提出这个问题的原因。相同的元素应该具有相同的名称,因为如果不这样做,事情就会变得糟糕。
  • 我很乐意 - 不幸的是,我无法控制 XML 的来源。我正在将其转换为 JSON,我只需要一种获取索引的方法,这样我就可以使 JSON 更合理。
  • 啊,我明白了。我什至不想让您更改源代码,我只是想让您不要创建同样损坏的目标 XML。但既然你转换成 JSON,没关系。 :) 您可以使用position() 来获取索引,您不必使用substring-after() 查看名称“后缀”。当然可以,但会更麻烦。
  • 如果我将其转换为 JSON,我会使用数组进行备份,例如 {"starter":"Another starter", "backups":["Backup1", "Backup2", "Backup3"], "reserves":["Reserve"]}

标签: xml xslt xpath


【解决方案1】:

如果您想要名称以backup 开头的所有元素,您可以使用

<xsl:for-each select="group/*[starts-with(local-name(), 'backup')]">

但具体取决于您尝试生成的输出类型,就模板匹配而不是 for-each 而言,这样做可能更简洁。

如果您特别想限制名称为“backup”后跟数字的元素(例如,不包括 backuptype 之类的内容),那么您可以添加到谓词中

group/*[starts-with(local-name(), 'backup')
    and number(substring(local-name(), 7)) = number(substring(local-name(), 7))]

(这看起来很奇怪,但诀窍是,如果 substring(local-name(), 7) 不是一个有效数字,那么测试将变为 NaN = NaN,这总是错误的 - NaN 不等于任何东西,甚至不等于它本身)。

【讨论】:

  • Ian,有没有办法获取索引,这样我就可以从backup1 和backup2 检索1 或2
  • @randombits 在for-each 中你可以取元素的local-name 的substring,或者你可以使用position() 函数来获取当前节点在你选择的列表中的位置。这可能与元素名称的尾随部分不同,例如如果该组有两个名为 backup2 和 backup5 的备份元素,那么 position() 仍然会给你 1 和 2,而 substring 会给你 2 和 5。
  • 感谢您精彩而详细的回答。只要允许,我就会将其标记为正确的。
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多