如何在导出到CSV文件时格式化MarkLogic结果

时间:2012-03-22 20:25:21

标签: csv formatting xquery extract marklogic

我的XML结构类似于下面的示例,我在MarkLogic中编写了一个XQuery,将其导出为CSV(参见下面的XML)。

我需要帮助的是格式化输出,以便在我打开CSV文件时,而不是将所有输出都放在1上,我希望它可以被分组为“列”。

让我们说下面的示例,我想输出所有的DataTime和Source元素值,并将值放在它们自己的列中,如下所示:

2012-02-15T00:58:26 a
2012-02-15T00:58:26 b
2012-02-15T00:58:26 c

我该怎么做?

欢迎任何参考点或帮助。提前谢谢。

以下是XML示例:

<Document xmlns="http://fakeexample.org/schemas">
    <Information>
        <ItemId>1f28cb0c2c4f4eb7b13c4abf998e391e</ItemId>
        <MediaType>Text</MediaType>
        <DocDateTime>2012-02-15T00:58:26</DocDateTime>
    </Information>
    <FilingData>
        <DateTime>2012-02-15T00:58:26</DateTime>
        <Source>a</Source>
        </FilingData>
    <FilingData>
        <DateTime>2012-02-15T00:58:27</DateTime>
        <Source>b</Source>
    </FilingData>
    <FilingData>
        <DateTime>2012-02-15T00:58:28</DateTime>
        <Source>c</Source>
    </FilingData>
</Document>

以下是XQuery示例:

xquery version "1.0-ml";

declare default function namespace "http://www.w3.org/2005/xpath-functions";
declare namespace xdmp="http://marklogic.com/xdmp";
declare namespace exam="http://fakeexample.org/schemas";

declare function local:getDocument($url)
{

let $response := xdmp:document-get($url, 
       <options xmlns="xdmp:document-get">
           <repair>full</repair>
           <format>xml</format>
       </options>)

return $response
};

xdmp:set-response-content-type("text/csv"),
xdmp:add-response-header(
      "Content-disposition",
      fn:concat("attachment;filename=", "output", fn:current-time(), ".csv")
    ),
(
let $q := cts:element-value-query(xs:QName("exam:ItemId"), ("1f28cb0c2c4f4eb7b13c4abf998e391e"))

let $results := cts:search(fn:doc(), $q)

for $result in $results
return  fn:string-join((xs:string($result//exam:DateTime),
                        xs:string($result//exam:Source)                     
                        ), "," )
)

2 个答案:

答案 0 :(得分:3)

用以下代码取代你的for循环:

return

string-join(
    for $result in $results//FilingData
    return  fn:string-join((xs:string($result//exam:DateTime),
                    xs:string($result//exam:Source)                     
                    ), "," )
, "&#10;")

应该做的就是诀窍......

修改:请注意,我在//FilingData后添加了$results。这样可以确保每个FilingData的DateTime和Source分别连接,并作为for循环的单独字符串返回。这允许外部字符串连接在它们之间添加所需的行结束。

注意:&#10;应自动转换为特定于操作系统的行结尾。

答案 1 :(得分:0)

以@grtjn的答案为基础:

string-join(..., "&#10;")

根据操作系统或应用程序,可以区别对待行结尾。您可以尝试替代字符(一个或两个):

"&#x0A;" (LF) 
"&#x0D;" (CR)

此外,用于查看CSV的应用程序可能会阻止这种情况。例如,大多数版本的Microsoft Excel会将单元格中的所有空格(包括换行符)转换为普通空格。