Проблема с BaseX XQuery при слиянии карт?

Я хочу преобразовать CSV в XML с помощью XQuery на BaseX (в настоящее время используется BaseX v9.4.1). Если табуляция столбцов разделена, CSV-файл Configuration.tsv (ввод) выглядит следующим образом:

Datasets    Autosar             Fibex           TSS0001  TSS0002  TSS0003
DS0001      AutosarFoo01.arxml  FibexFoo01.xml  x        x  
DS0002      AutosarFoo02.arxml  FibexFoo02.xml  x                 x
DS0003      AutosarFoo03.arxml  FibexFoo03.xml  x                 x

Скрипт имеет tssid в качестве входного параметра. Установка tssid := TSS0001 ожидаемого вывода XML:

<database name="DS0001" autosar="AutosarFoo01.arxml" fibex="FibexFoo01.arxml"/>
<database name="DS0002" autosar="AutosarFoo02.arxml" fibex="FibexFoo02.arxml"/>
<database name="DS0003" autosar="AutosarFoo03.arxml" fibex="FibexFoo03.arxml"/>

и с tssid := TSS0003:

<database name="DS0002" autosar="AutosarFoo02.arxml" fibex="FibexFoo02.arxml"/>
<database name="DS0003" autosar="AutosarFoo03.arxml" fibex="FibexFoo03.arxml"/>

Скрипт работает нормально, но значение третьего атрибута (fibex) отсутствует, поэтому результат выглядит иначе:

<database name="DS0001" autosar="AutosarFoo01.arxml" fibex=""/>
<database name="DS0002" autosar="AutosarFoo02.arxml" fibex=""/>
<database name="DS0003" autosar="AutosarFoo03.arxml" fibex=""/>

или с tssid := TSS0003:

<database name="DS0002" autosar="AutosarFoo02.arxml" fibex=""/>
<database name="DS0003" autosar="AutosarFoo03.arxml" fibex=""/>

Я не могу найти что-то не так с этим кодом?!? :

xquery version "3.1" encoding "utf-8";

declare namespace test="unittest";

declare namespace map="http://www.w3.org/2005/xpath-functions/map";

declare variable $test:tssid := 'TSS0003';

declare variable $test:testsuitesfile := '/Users/ms/Projekte/UnitTests/Configuration.tsv';

declare variable $test:options := map { 'header' : 'yes', 'format' : 'attributes', 'separator' : 'tab' };

declare variable $test:xml := csv:doc($test:testsuitesfile,$test:options);

(: get the positions :)

declare variable $test:positionDataId := 1 ;

declare variable $test:positionTssCheck := $test:xml/csv/record[position() = 1]/entry[text() = $test:tssid]/count(./preceding-sibling::entry) + 1 ;

declare variable $test:positionAutosar := $test:xml/csv/record[position() = 1]/entry[text() = 'Autosar']/count(./preceding-sibling::entry) + 1 ;

declare variable $test:positionFibex := $test:xml/csv/record[position() = 1]/entry[text() = 'Fibex']/count(./preceding-sibling::entry) + 1 ;

declare variable $test:dbsetbycsv as map(*) := map:merge(for $record in $test:xml/csv/record[entry[position() = $test:positionTssCheck and text()='x']] return map:entry($record/entry[position() = $test:positionDataId]/text(),<database name="{$record/entry[position() = $test:positionDataId]/text()}" autosar="{$record/entry[position() = $test:positionAutosar]/text()}" fibex="{$record/entry[position() = $test:positionFibex]/text()}"/>));

declare variable $test:dbset := $test:dbsetbycsv;

declare function test:dump() {
  for-each(
    map:keys($test:dbset),
    function($k) { 
      $test:dbset($k)
    }
  )
};

let $result := test:dump()

return($result)

person Community    schedule 01.09.2020    source источник
comment
Когда я пробую ваш код как есть, переменные $test:positionTssCheck, $test:positionAutosar и $test:positionFibex представляют собой пустую последовательность (), потому что вы указали 'header' : 'yes' в параметрах синтаксического анализа CSV, и поэтому заголовки столбцов находятся в атрибутах <entry name="...", а не в text() узлах первого линия. Когда я меняю три строки на $test:xml/csv/record[position() = 1]/entry[@name = '...']/... (заменяя text() на @name), все работает, как ожидалось. Не могли бы вы обновить код, чтобы он соответствовал описанному вами результату?   -  person Leo Wörteler    schedule 01.09.2020
comment
@ LeoWörteler благодарим за ответ. Вы можете найти образец кода и данных здесь. ScriptOrig.xqy не работает должным образом, но ScriptModified.xqy работает нормально.   -  person    schedule 02.09.2020


Ответы (2)


Кажется, что

$xml/csv/record[entry[@name = $tssid and . = 'x']] ! <database name="{entry[@name = 'Datasets']}" autosar="{entry[@name = 'Autosar']}" fibex="{entry[@name = 'Fibex']}"/>

может быть достаточно, учитывая, что entry элементы имеют name атрибуты.

person Martin Honnen    schedule 01.09.2020

Это ошибка. Исправлено теперь в бета-версии BaseX 9.4.3.

person Community    schedule 01.09.2020
comment
Код, который вы здесь показываете, не компилируется, ему требуется как минимум let перед $fibex := [...]. Но если извлечение значения атрибута в переменную, привязанную к let, действительно меняет результат в этом случае (с устранением других проблем), вы действительно могли найти ошибку в BaseX. Однако я не могу воспроизвести его с помощью предоставленного вами кода. - person Leo Wörteler; 01.09.2020
comment
@ LeoWörteler благодарим за ответ. Да, let отсутствует. Итак, здесь вы найдете образец кода и данные. ScriptOrig.xqy не работает должным образом, но ScriptModified.xqy работает нормально. Я предполагаю, что что-то идет не так с оценкой переменных в части значения map:entry(). - person ; 02.09.2020