Файл XQuery: запись записывает только одну строку

Я хотел бы, чтобы приведенный ниже запрос записывал результаты в файл xml. В настоящее время он записывает только первый элемент результата в файл xml, независимо от того, сколько элементов есть.

Почему это происходит и как я могу это исправить?

let $fName := "C:\Users\user\Documents\Sitemaps\Updated Pages\Books.xml"

for $x in doc("http://www.w3schools.com/xsl/books.xml")/bookstore/book
where $x/price>0
return file:write($fName,$x/title)

person V.S.    schedule 19.01.2016    source источник
comment
К вашему сведению, StackSnippets предназначены только для кода, который может быть выполнен в браузере (как правило, JavaScript/CSS/и т. д.). Для XQuery следует использовать кнопку {} в редакторе StackOverflow для обычного форматирования кода.   -  person Charles Duffy    schedule 20.01.2016


Ответы (3)


file:write() не является функцией стандартного языка и зависит от побочных эффектов, поэтому эффект, вероятно, будет зависеть от того, какой процессор XQuery вы используете. Вы даже не показали объявление пространства имен, так что мы не можем сказать, должно ли это быть вызовом функции EXPath file:write().

Если предположить, что это вызов функции EXPath file:write(), то эффект file:write() должен быть писать все содержимое файла, а не добавлять в файл. Если вы хотите дополнить файл, используйте file:append(). Однако в этой ситуации я бы инстинктивно записал все элементы в файл за одну операцию, то есть:

let $doc := doc("http://www.w3schools.com/xsl/books.xml")
return file:write($fName, $doc/bookstore/book[price>0]/title)
person Michael Kay    schedule 20.01.2016

Основываясь на вашем коде, я ожидаю, что он напишет только последний заголовок в документе. Вы не говорите, какой процессор XQuery вы используете, но, возможно, это поведение, определяемое реализацией, что может быть эквивалентом ошибки «конфликтующие обновления».

Оберните весь запрос в элемент XML (недопустимо создавать XML с несколькими корневыми узлами) и запишите весь этот документ на диск (вызвав file:write только один раз):

file:write($fName,
  element titles {
    for $x in doc("http://www.w3schools.com/xsl/books.xml")/bookstore/book
    where $x/price>0
    return $x/title
  })
person wst    schedule 19.01.2016

Для BaseX вызов file:write() перезапишет любое существующее содержимое файла. Вы вызываете его для каждого элемента, поэтому последний «выиграет».

http://docs.basex.org/wiki/File_Module#file:write

Записывает сериализованную последовательность элементов в указанный файл. Если файл уже существует, он будет перезаписан.

Вы должны либо изменить свой XQuery, чтобы записать последовательность элементов, как предлагает @wst, либо убедиться, что каждый элемент записан с уникальным URI файла.

person Mads Hansen    schedule 20.01.2016