2

有 2 个具有不同命名空间的 xml 文档,例如

declare namespace ml1 = "urn:schemas-com:ml1";
declare namespace ml2 = "urn:schemas-com:ml2";

但具有相同的结构。我可以选择仅使用这些命名空间而不使用 * 的一些节点吗?我的意思是这样的:

fn:doc($uri)/(ml1 or ml2):root

更新: 谢谢。所有建议都有效,但对我没有用。因为可以有3个或更多的命名空间,xpath表达式会很大。有什么建议么?

结论: 感谢您的回答。我同意@MichaelKay 的观点,即我应该处理所有 xml 所有文档。问题解决了。

4

4 回答 4

3

一种可能的表达方式是

  doc($uri)/(ml1:root|ml2:root)

另一个是

  doc($uri)/*[self::ml1:root or self::ml2:root]

如果可以有无限数量的形式前缀"mlNNNNN"",请使用:

  doc($uri)/*[matches(substring-before(name(), ':'), '^ml\d+')]
于 2012-08-07T13:10:16.963 回答
3

您可以使用谓词

fn:doc($uri)/*[local-name() = "root" and (namespace-uri() = "urn:schemas-com:ml1" or namespace-uri() = "urn:schemas-com:ml2")]

如果您的命名空间 URI 都有一个共同的前缀(正如您提供的示例所建议的那样),那么您可以使用类似的结构

..../*[starts-with(namespace-uri(), "urn:schemas-com:") ...]

如果您有许多命名空间,并且可以在另一个 XML 文件中将它们全部列出:

<namespaces>
  <uri>urn:schemas-com:ml1</uri>
  <uri>urn:schemas-com:ml2</uri>
  <!-- ... -->
</namespaces>

然后是谓词

*[namespace-uri() = fn:doc("namespaces.xml")/namespaces/uri]

如果正在测试的节点的命名空间URInamespaces.xml.

于 2012-08-07T13:12:15.423 回答
2
let $qnames :=
  for $ns in ("urn:schemas-com:ml1", "urn:schemas-com:ml2")
  return QName($ns, 'root')
return doc($uri)/*[node-name(.) = $qnames]

查找应使用node-name索引。

或者您可以使用字符串操作来构建路径,然后调用xdmp:unpath来评估它:http ://docs.marklogic.com/5.0doc/docapp.xqy#display.xqy?fname=http://pubs/5.0doc/ apidoc/ExsltBuiltins.xml&category=扩展&function=xdmp:unpath

于 2012-08-07T14:35:26.803 回答
2

当您遇到此问题时,最好的解决方案是从规范化命名空间开始:也就是说,进行转换以使所有文档都采用通用格式,然后将 XPath 表达式应用于规范化表单。

于 2012-08-07T15:00:12.493 回答