XQuery/XPath 与 Saxon API - 需要不区分大小写的路径
XQuery/XPath with Saxon API - Case Insensitive Paths Needed
简而言之,我希望以下所有路径的计算结果相同:
- /root/item1/text()
- /ROOT/ITEM1/text()
- /Root/Item1/text()
据我了解,这个想法是 XML 大小写不同的节点实际上被视为不同的。这里的问题是我正在构建一个基于一组关系 SQL 数据库表的动态 XML 构建器。该应用程序将安装在 50 多台不同的服务器上,它们有自己的 SQL 个实例。 50% 的表结构、名称和类型会有所不同,而另外 50% 的表名称的字母大小写可能会有所不同。目标是将标准 XQuery 转换应用于这些动态生成的 XML 文件,这些文件具有自定义和标准部分,标准意味着它适用于所有 50 多个服务器。这就是为什么我要寻找不区分大小写的路径逻辑,即使它违背了 XML 的基本原理,它也会为我们的用例 "opt" 提供这样的能力带来巨大的好处。
我目前用于测试的一个有用的解决方法是使用 XSLT 进行预转换,将所有元素节点名称转换为小写。所以如果没有结果,那么至少它仍然是可行的。
我是 XQuery/XPath/XSLT 的新手,所以命名空间对我来说仍然是一个陌生的概念。我偶然发现的一件事是声明排序规则。但是我不知道这是否仅用于典型的字符串比较($x = $y)或其他类似的事情。 Saxon 有一个名为 Processor.DeclareCollation() 的处理器内置方法,我尝试使用它,但是我没有注意到查询 运行 有任何不同。
整理是我的答案吗,只是如何设置它的问题(在此之前从未真正搞砸过)?还有另一种方法可以解决这个问题吗?还是我应该坚持现有的解决方案?
*P.S。具有不区分大小写的函数名称也将是一个很棒的奖励 [text() vs TEXT()] 但我可以没有它,这将有助于我团队中的小白经历更少的错误。 :)
这个 XPath,
/*[lower-case(name()) = "root"]/*[lower-case(name()) = "item1"]/text()
将以不区分大小写的方式介绍您的示例。
备注:
- 请不要这样做。 XML 在设计和标准化方面区分大小写。
- 不,没有声明不区分大小写的全局方式。参见#1。
- 不,标准不应该屈服于特殊的设计;特殊的设计应该屈服于它。
XML 本质上区分大小写。在编写必须处理可变输入格式的转换时,我通常的建议是将它们编写为管道,其中第一阶段摆脱不必要的变化,以便 "business logic" 阶段可以专注于一个任务而不会分心不同的输入表示。
这基本上是@MadsHansen 提出的解决方案。
另一种方法(在 Saxon 中)虽然有点复杂,但可能很简洁:您可以实现一个自定义树模型,其中元素和属性的名称以规范化的大小写显示,隐藏任何大小写变化基础数据。 Saxon 中有很多机制用于实现自定义树模型作为其他树模型的包装器,因此实际上不会有大量代码;但是充分熟悉 Saxon 的内部结构以使其正常工作将是一项重大挑战。
不过,我真正的建议是不要从这里开始。您设计 XML 词汇表的方式被误导了。在XML中,"Straße"和"STRASSE"是不同的名字,所有XML工具都会把它们当作不同的名字,如果你想把它们当作替代方式如果写同一个名字,那么你就违背了自然流程,这总是会增加复杂性和成本。
在 XPath 中,排序规则对于比较用户数据很有用:您可以采用一种排序规则,其中字符串 "Straße" 和 "STRASSE" 在出现在元素和属性的文本内容中时被认为是等价的.但是在比较元素和属性名称时从不使用它们。
简而言之,我希望以下所有路径的计算结果相同:
- /root/item1/text()
- /ROOT/ITEM1/text()
- /Root/Item1/text()
据我了解,这个想法是 XML 大小写不同的节点实际上被视为不同的。这里的问题是我正在构建一个基于一组关系 SQL 数据库表的动态 XML 构建器。该应用程序将安装在 50 多台不同的服务器上,它们有自己的 SQL 个实例。 50% 的表结构、名称和类型会有所不同,而另外 50% 的表名称的字母大小写可能会有所不同。目标是将标准 XQuery 转换应用于这些动态生成的 XML 文件,这些文件具有自定义和标准部分,标准意味着它适用于所有 50 多个服务器。这就是为什么我要寻找不区分大小写的路径逻辑,即使它违背了 XML 的基本原理,它也会为我们的用例 "opt" 提供这样的能力带来巨大的好处。
我目前用于测试的一个有用的解决方法是使用 XSLT 进行预转换,将所有元素节点名称转换为小写。所以如果没有结果,那么至少它仍然是可行的。
我是 XQuery/XPath/XSLT 的新手,所以命名空间对我来说仍然是一个陌生的概念。我偶然发现的一件事是声明排序规则。但是我不知道这是否仅用于典型的字符串比较($x = $y)或其他类似的事情。 Saxon 有一个名为 Processor.DeclareCollation() 的处理器内置方法,我尝试使用它,但是我没有注意到查询 运行 有任何不同。
整理是我的答案吗,只是如何设置它的问题(在此之前从未真正搞砸过)?还有另一种方法可以解决这个问题吗?还是我应该坚持现有的解决方案?
*P.S。具有不区分大小写的函数名称也将是一个很棒的奖励 [text() vs TEXT()] 但我可以没有它,这将有助于我团队中的小白经历更少的错误。 :)
这个 XPath,
/*[lower-case(name()) = "root"]/*[lower-case(name()) = "item1"]/text()
将以不区分大小写的方式介绍您的示例。
备注:
- 请不要这样做。 XML 在设计和标准化方面区分大小写。
- 不,没有声明不区分大小写的全局方式。参见#1。
- 不,标准不应该屈服于特殊的设计;特殊的设计应该屈服于它。
XML 本质上区分大小写。在编写必须处理可变输入格式的转换时,我通常的建议是将它们编写为管道,其中第一阶段摆脱不必要的变化,以便 "business logic" 阶段可以专注于一个任务而不会分心不同的输入表示。
这基本上是@MadsHansen 提出的解决方案。
另一种方法(在 Saxon 中)虽然有点复杂,但可能很简洁:您可以实现一个自定义树模型,其中元素和属性的名称以规范化的大小写显示,隐藏任何大小写变化基础数据。 Saxon 中有很多机制用于实现自定义树模型作为其他树模型的包装器,因此实际上不会有大量代码;但是充分熟悉 Saxon 的内部结构以使其正常工作将是一项重大挑战。
不过,我真正的建议是不要从这里开始。您设计 XML 词汇表的方式被误导了。在XML中,"Straße"和"STRASSE"是不同的名字,所有XML工具都会把它们当作不同的名字,如果你想把它们当作替代方式如果写同一个名字,那么你就违背了自然流程,这总是会增加复杂性和成本。
在 XPath 中,排序规则对于比较用户数据很有用:您可以采用一种排序规则,其中字符串 "Straße" 和 "STRASSE" 在出现在元素和属性的文本内容中时被认为是等价的.但是在比较元素和属性名称时从不使用它们。