首页 > 解决方案 > XML 节点替换失败

问题描述

我尝试使用 Corb 在大量文档中搜索和更新节点:

样本输入:

<hcmt xmlns="http://horn.thoery">
  <susceptible>X</susceptible>
  <reponsible>foresee–intervention</reponsible>
  <intend>Benefit Protagonist</intend>
  <justified>Goal Outwiegen</justified>
</hcmt> 

查询:

(: let $resp   :=  "foresee–intervention" :)
 
let $docs :=    
  cts:search(doc(),
  cts:and-query((
  cts:collection-query("hcmt"),
  cts:path-range-query("/horn:hcmt/horn:responsible", "=", $resp)
        ))
    )
return
  for $doc in $docs
return
  xdmp:node-replace($doc/horn:hcmt/horn:responsible, "Foresee Intervention")

预期输出:

<hcmt xmlns="http://horn.thoery">
  <susceptible>X</susceptible>
  <reponsible>Foresee Intervention</reponsible>
  <intend>Benefit Protagonist</intend>
  <justified>Goal Outwiegen</justified>
</hcmt>

但是在 Corb 中没有发生节点替换,也没有错误返回。其他查询在 Corb 中运行良好。节点替换如何在 Corb 中正常工作?

提前感谢您的帮助。

标签: javaxsltnosqlxquerymarklogic

解决方案


我创建函数来协调编码问题。这不仅可以缓解潜在的 API 事务失败,而且还是验证和编码参数或元素/属性/uri 名称的必要条件。

也就是说,一个示例 MarkLogic Java API 实现是:

  1. 在我的情况下,在文件系统中创建一个动态查询构造product-query-option.xml(直接使用查询值Chooser–Option:)
<search xmlns="http://marklogic.com/appservices/search">
    <query>
        <and-query>
            <collection-constraint-query>
                <constraint-name>Collection</constraint-name>
                <uri>proto</uri>
            </collection-constraint-query>
            <range-constraint-query>
                <constraint-name>ProductType</constraint-name>
                <value>Chooser–Option</value>
            </range-constraint-query>
        </and-query>
    </query>
</search>
  1. 将持久查询选项部署到模块数据库,在我的例子中search-lexis.xml,选项文件如下:
<options xmlns="http://marklogic.com/appservices/search">
     <constraint name="Collection">
         <collection prefix=""/>
     </constraint>
     <constraint name="ProductType">
        <range type="xs:string" collation="http://marklogic.com/collation/en/S1">
          <path-index xmlns:prod="schema://fc.fasset/product">/prod:requestProduct/prod:_metaData/prod:productType</path-index>
        </range>
     </constraint>
</options>
  1. 动态 Java 搜索开始
        File file = new File("src/main/resources/queryoption/product-query-option.xml");

        FileHandle fileHandle = new FileHandle(file);

        RawCombinedQueryDefinition rcqDef = queryMgr.newRawCombinedQueryDefinition(fileHandle, queryOption);
  • 当然,您可以将查询和选项组合为QueryDefinition.
  1. 您原来的 node-replace 被翻译为Java Partial Update
  • 确保DocumentPatchBuilder setNamespaces使用正确的NamespaceContext.
  1. 对于批处理数据操作,高效的方法是 MarkLogic 数据移动:QueryBatcher使用搜索到的 Uris 实例化 ,提供替换值或数据片段PatchBuilder.replaceValue ,并完成批处理 dbClient.newXMLDocumentManager().patch(uri, patchHandle);

MarkLogic 数据服务:如果您在上述方面取得了成功,那么可能会采用更健壮和可扩展的企业 SOA 方法,请查看数据服务

  • Gradle 的实现如下:

数据服务实现

(注意,所有的转换指标都应该是参数,包括路径/元素/属性名称、命名空间、值……等等。没有什么是硬编码的。) 中声明的一个代理服务service.json可以为多个端点(在 下/root/df-ds/fxd)提供不同类型的模块,这些模块让您自由开发纯 Java 或扩展开发平台以处理复杂的数据操作。

如果这些操作是持久节点更新,则应在摄取之前考虑内存中节点转换。除了 MarkLogic 数据转换工具,您还可以利用 XSLT2+ 的强大功能。

SaxonXPathFactory可能是查询/转换节点的可用工具。不确定是否是互惠的,ML Java API 实现了 XPathcompile来拆分大路径和流事务。XSLT/Saxon 不是我的强项;因此,我无法评论它与这种编码/解码特性的可比性或它如何处理事务(插入、更新……等)流。


推荐阅读