XQuery - неверные индексы в подстроке после использования функции обратной строки
Я пытаюсь реализовать base64-кодирование очень простым способом. В моем подходе (давайте на секунду уберем, уместно ли это или нет), мне нужно перевернуть строки и затем констатировать их. После этого эта объединенная строка используется в функции подстроки. Строки соединяются правильно, но при использовании подстроки basex, похоже, теряет ее.
Самое смешное, что подстрока работает хорошо для всех индексов, начиная с 8. Поэтому подстрока ($string, 1, 8) и выше дает правильный вывод. Но все, что ниже, запутано. Начиная с одного исчезнувшего числа: подстрока ($string, 1, 7 (и ниже)) приводит к длине строки 6. Причем подстрока может начинаться только с 1-го или 0-го индекса. Все, что больше, приводит к пустому возврату.
declare variable $array := []; declare function bs:encode ( $input as xs:string ) { bs:integer-to-binary(string-to-codepoints($input), "", $array) } ; declare function bs:integer-to-binary ( $input as xs:integer*, $string as xs:string, $array as array(xs:string) ) { let $strings := for $i in $input return if ($i != 0) then if ($i mod 2 = 0) then bs:integer-to-binary(xs:integer($i div 2), concat($string, 0), $array) else bs:integer-to-binary(xs:integer($i div 2), concat($string, 1), $array) else if ($i <= 0) then array:append($array, $string) return bs:check-if-eight($strings) } ; declare function bs:check-if-eight ( $strings as item()+ ) { let $fullBinary := for $string in $strings return if (string-length($string) < 8) then bs:check-if-eight(concat($string, 0)) else $string (: add as private below :) return bs:concat-strings($fullBinary) } ; declare function bs:concat-strings ( $strings as item()+ ) { let $firstStringToConcat := functx:reverse-string($strings[position() = 1]) let $secondStringToConcat := functx:reverse-string($strings[position() = 2]) let $thirdStringToConcat := functx:reverse-string($strings[position() = 3]) let $concat := concat ($firstStringToConcat, $secondStringToConcat, $thirdStringToConcat) (: this returns correct string of binary value for Cat word :) return bs:divide-into-six($concat) } ; declare function bs:divide-into-six ( $binaryString as xs:string) { let $sixBitString := substring($binaryString, 1, 6) (: this should return 010000 instead i get 000100 which is not even in $binaryString at all :) return $sixBitString } ; bs:encode("Cat")
Я ожидаю первые шесть букв от строки (010000), вместо этого я получаю некоторую случайную последовательность, я думаю (00100). Весь модуль предназначен для кодирования строк в формате base64, но сейчас (часть, которую я загрузил) должна просто выбросить первые шесть битов для 'C'
1 ответ
Хорошо, так что я понял это, я думаю.
Прежде всего в функции concat-strings я изменил concat на fn:string-join. Это позволило мне передать в качестве аргумента символ, который разделяет соединенные строки.
declare function bs:concat-strings ( $strings as item()+ ) { let $firstStringToConcat := xs:string(functx:reverse-string($strings[position() = 1])) let $secondStringToConcat := xs:string(functx:reverse-string($strings[position() = 2])) let $thirdStringToConcat := xs:string(functx:reverse-string($strings[position() = 3])) let $concat := ****fn:string-join(**** ($firstStringToConcat, $secondStringToConcat, $thirdStringToConcat),****'X'****) return bs:divide-into-six($concat) } ;
Я увидел, что мой ввод выглядел так:
Очевидно, он должен был зацикливаться где-то без цикла for clear, и, поскольку я новичок в Xquery, я, должно быть, пропустил это. И действительно. Я нашел это в функции проверки-восемь:
> declare function bs:check-if-eight ( $strings as item()+ ) { > **let $fullBinary :=** > for $string in $strings > return if (string-length($string) < 8) > then bs:check-if-eight(concat($string, 0)) > else $string (: add as private below :) > **return bs:concat-strings($fullBinary)** } ;
Несмотря на то, что он был выше ключевого слова FOR, переменная $fullBinary находилась в цикле и создавала пустые пробелы (?), И это было ясно показано, когда я использовал X в качестве разделителя. ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я думал об этом раньше и использовал functx:trim, но по какой-то причине он работает не так, как я ожидал. Так что это может быть не для вас, если есть аналогичные проблемы.
В этот момент стало ясно, что let $fullBinary не может быть подана в выражении FLWR, по крайней мере, не может вызвать функцию concat-strings. Я изменил его, и теперь он производит только строку, и теперь я пытаюсь выяснить новую последовательность запуска всего модуля, но я думаю, что основная проблема здесь решена.