【问题标题】:XPath 匹配不区分大小写的标签
【发布时间】:2022-01-23 11:14:59
【问题描述】:

我有一个提要 XML,我想在文件中选择 items

<xml>
  <item>
    ...
  </item>
  <item>
    ...
  </item>
  <item>
    ...
  </item>
</xml>

但用户可以传递标签名称,如&lt;Item&gt;&lt;ITEM&gt; 或类似的东西。如何编写 XPath 来选择不区分大小写的项目?

【问题讨论】:

  • 最好先做一个转换步骤,例如XSLT 或 XQuery 在开始使用 XPath 处理之前规范化元素名称中的字母大小写,否则您会得到相当长且可能效率低下的表达式,必须 lower-case 或(在 XPath 1.0 中)translate 每个名称

标签: xml xpath


【解决方案1】:

有两种方法可以做到这一点:

  1. 利用 XPath 2.0 lower-case 字符串函数:
//*[lower-case(name())='item']
  1. 带有matches() XPATH 2.0 功能
    matches() 函数标志之一是 i,用于不区分大小写的匹配。
//*[matches(name(),'item','i')]

UPD
我不知道与 XPath 1.0 的真正不区分大小写匹配
你可以做的是使用or case,比如:

//*[name()='item' or name()='Item' or name()='ITEM']

【讨论】:

  • 有什么方法可以实现这些 XPath 1.0 吗?
  • 请看我更新的答案
  • 可能有不同的标签名称,例如entryproduct等,也可以是itEm
  • 好吧,entryproduct 不是不区分大小写的 item... 因此,您可以并且应该使用 UPD 部分中提到的 or 大小写和只需明确提及所有这些选项
【解决方案2】:

在 XPath 1.0 中,您可以使用例如//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'item'] 但正如我在评论中所说,请考虑在转换步骤中预处理 XML 以规范字母的大小写,然后在第二步中使用像 //item 这样的普通 XPath 选择器。

【讨论】:

  • 此时出现了另一个问题。当我执行这条线时,它工作正常doc.xpath("/rss/channel/*[translate(local-name(), \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\", \"abcdefghijklmnopqrstuvwxyz\") = 'item']")。但是把/rss/channel/换成//就不行了。
  • 也许将其作为一个包含所有详细信息的单独问题提出,或者编辑问题并在那里显示详细信息。
猜你喜欢
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
相关资源
最近更新 更多