我正在尝试以一种非常简单的方式实现base64编码。在我的方法中(不管是否合适,请先搁置一秒钟),我需要反转字符串,然后将它们连接起来。之后,此缩略的字符串用于子字符串功能。字符串已正确连接,但是当我使用substring时,basex似乎会丢失它。
有趣的是子串对于从8开始的所有索引都适用。因此,子串($ string,1,8)和更高的子串给出正确的输出。但是下面的所有东西都弄糟了。以一个消失的数字开头:substring($ string,1,7(及以下))产生6个长度的字符串。 此外,子字符串只能以1st或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'的前六位抛出
答案 0 :(得分:0)
好的,所以我猜出来了。
首先在函数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) } ;
我看到我的输入看起来像这样: XXXXXXXX01000011XXXXXXXXXXXXXXXXX01100001XXXXXXXXXXXXXXXXX01110100XXXXXXXX
很显然,它必须在没有明确for循环的地方循环,而且当我刚接触Xquery时,我一定很想念它。的确如此。我在check-if-eight函数中找到了它:
> 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,但由于某些原因,它没有按我预期的那样工作。因此,如果遇到类似的问题,可能也不太适合您。
在这一点上,很明显,不能在FLWR语句中让$ fullBinary投标,至少不能触发concat-strings函数。我更改了它,现在它仅生成字符串,现在我试图找出运行整个模块的新顺序,但我认为这里的主要问题已解决。