Как форматировать результаты MarkLogic при экспорте в файл CSV

У меня есть XML, структура которого аналогична приведенному ниже примеру, и я написал XQuery в MarkLogic, чтобы экспортировать его в 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)                     
                        ), "," )
)

person zrdunlap    schedule 22.03.2012    source источник


Ответы (2)


Замените цикл 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. Это гарантирует, что DateTime и Source каждого FilingData объединяются отдельно и возвращаются в виде отдельных строк цикла for. Это позволяет внешнему соединению строк добавлять между ними требуемые концы строк.

Примечание. &#10; следует автоматически преобразовывать в окончания строк, специфичные для ОС.

person grtjn    schedule 22.03.2012
comment
Вам не нужно беспокоиться об экранировании строк, новых строк и кавычек из содержимого? (Кстати, я бы хотел, чтобы побег был библиотекирован, чтобы его можно было использовать повторно :) - person Eric Bloch; 23.03.2012
comment
@eric-bloch С данным XML нет. ;-) - person grtjn; 23.03.2012
comment
Спасибо за ответ, к сожалению, он по-прежнему записывает результаты в 1 строку, например: date1, date2, date3, source1, source2, source3. Глядя на выяснение того, как использовать карты сейчас. Опубликую обновление, если я заставлю его работать. - person zrdunlap; 23.03.2012
comment
@zrdunlap Ах, этот cts:search возвращает целые документы, в то время как вы хотите, чтобы каждый файл FilingData находился в отдельной строке. Вам нужно выбрать тех. Вы можете возиться с cts:search, но, возможно, проще добавить путь к ним в цикле for. Я отредактирую свое решение. - person grtjn; 24.03.2012
comment
Вот и все! Благодарю вас! Я знал, что что-то упускаю. - person zrdunlap; 24.03.2012

Основываясь на ответе @grtjn:

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

Концы строк могут обрабатываться по-разному в зависимости от ОС или приложения. Вы можете попробовать альтернативные символы (любой или оба):

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

Кроме того, этому может помешать приложение, используемое для просмотра CSV. Например, большинство версий Microsoft Excel преобразуют все пробелы в ячейке, включая символы новой строки, в простые пробелы.

person wst    schedule 23.03.2012
comment
Спасибо, попробовал и то, и другое и все еще получаю: 2012-02-15T00:58:26,2012-02-15T00:58:26,2012-02-15T00:58:27,2012-02-15T00:58 :28,a,b,c Я уверен, что делаю что-то не так, но еще не понял, что именно. - person zrdunlap; 23.03.2012