You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用xdmp:save导出MarkLogic数据到CSV?CSV无法换行追加排查

Fixing CSV Row Appending in MarkLogic XQuery

Hey there! I see you're trying to generate a CSV file in MarkLogic using XQuery but hitting a wall with appending rows instead of overwriting the file each time. Let's work through this together.

First, here's your code snippet formatted properly for clarity:

xquery version "1.0-ml"; 
let $filename := "D:\csv-reports\test.csv" 
let $directory-query := cts:directory-query("/searcdoc/") 
let $uris := cts:uris((), (), $directory-query) 
for $uri in $uris 
let $additional := doc($uri)/searcdoc/access/additional/text() 
let $des := doc($uri)/searcdoc/std/text() 
let $option := <options xmlns="xdmp:save">
                 <!-- Your existing options here -->
               </options>
<!-- I assume you're calling xdmp:save here but missing append config -->

The Core Problem

By default, xdmp:save overwrites the target file entirely every time it runs. That means in your loop, each iteration is replacing the CSV with just the current row, instead of adding it to the end. You're missing the critical append configuration in your xdmp:save options.

The Fix: Enable Append Mode

To make xdmp:save append content instead of overwriting, you need to add the <append>true</append> element to your save options. Also, you'll want to handle the CSV header only once (when the file is first created) to avoid repeating it on every append.

Here's an updated, working version of your code:

xquery version "1.0-ml"; 

let $filename := "D:\csv-reports\test.csv"
let $directory-query := cts:directory-query("/searcdoc/")
let $uris := cts:uris((), (), $directory-query)

// Check if the CSV file already exists to handle header logic
let $file-exists := xdmp:file-exists($filename)

// Define your CSV header (write this only once)
let $csv-header := "additional,description" || xdmp:newline()

// Configure save options to enable append mode
let $save-options := 
  <options xmlns="xdmp:save">
    <append>true</append>
  </options>

// Write header if the file is new
let $_ := if (not($file-exists)) then xdmp:save($filename, $csv-header, $save-options) else ()

// Loop through URIs and append each row to the CSV
for $uri in $uris
let $additional := doc($uri)/searcdoc/access/additional/text()
let $des := doc($uri)/searcdoc/std/text()
// Escape special characters (like commas/quotes) for valid CSV
let $escaped-additional := '"' || fn:replace($additional, '"', '""') || '"'
let $escaped-des := '"' || fn:replace($des, '"', '""') || '"'
let $csv-row := $escaped-additional || "," || $escaped-des || xdmp:newline()
return xdmp:save($filename, $csv-row, $save-options)

Key Details to Note:

  • <append>true</append>: This is the missing piece—it tells MarkLogic to add content to the end of the file instead of replacing it.
  • Header Handling: Using xdmp:file-exists ensures we only write the header once when the file is first created, so you don't get duplicate headers in your CSV.
  • CSV Escaping: I added logic to wrap values in quotes and escape internal quotes (replacing " with "")—this is crucial for valid CSV if your data contains commas or quotes.

This should resolve your issue—now each row will be appended to the CSV instead of overwriting the entire file!

内容的提问来源于stack exchange,提问作者subsoft

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:08:10