XQuery-使用反向字符串函数后子字符串中的索引错误

XQuery-使用反向字符串函数后子字符串中的索引错误,xquery,basex,functx,Xquery,Basex,Functx,我试图以一种非常简单的方式实现base64编码。在我的方法中(让我们暂时搁置它是否合适),我需要反转字符串,然后将它们合并。之后,这个具体的字符串用于子字符串函数。字符串是正确连接的,但当我使用子字符串basex时,它似乎丢失了 有趣的是,子字符串对于从8开始的所有索引都很有效。因此,子字符串($string,1,8)和更高的值给出正确的输出。但下面的一切都是一团糟。从一个消失的数字开始:子字符串($string,1,7(及以下))产生长度为6的字符串。 此外,子字符串只能以1或0索引开始。任何

我试图以一种非常简单的方式实现base64编码。在我的方法中(让我们暂时搁置它是否合适),我需要反转字符串,然后将它们合并。之后,这个具体的字符串用于子字符串函数。字符串是正确连接的,但当我使用子字符串basex时,它似乎丢失了

有趣的是,子字符串对于从8开始的所有索引都很有效。因此,子字符串($string,1,8)和更高的值给出正确的输出。但下面的一切都是一团糟。从一个消失的数字开始:子字符串($string,1,7(及以下))产生长度为6的字符串。 此外,子字符串只能以1或0索引开始。任何更大的结果都是空回报

声明变量$array:=[];
声明函数bs:encode
($input作为xs:string){
bs:整数到二进制(字符串到码点($input),“”,$array)
} ;
将函数bs:整数声明为二进制
($input作为xs:integer*,$string作为xs:string,$array作为array(xs:string)){
让$strings:=
在$input中输入$i
返回
如果($i!=0)
那么如果($i mod 2=0)
然后将bs:integer转换为二进制(xs:integer($i div 2),concat($string,0),$array)
else-bs:integer到二进制(xs:integer($i div 2),concat($string,1),$array)

否则,如果($i好的,那么我想我已经弄明白了

首先,在函数concat-strings中,我将concat改为fn:string-join。它允许我作为分隔连接字符串的参数符号进行传递

我看到我的输入是这样的: XXXXXXXX 010000111XXXXXXXXXXXXXXXXXXXXXXXXXXXX00110000XXXXXXXXXXXXXXXXXXXXXXXX001110100XXXXXXXXXXXX

显然,它必须在没有clear for loop的地方循环,作为Xquery的新手,我一定错过了这一点。事实上,我在检查8个函数时发现了它:

>声明函数bs:检查是否有八个($strings as item()+){
>**让$fullBinary:=**
>对于$string中的$string
>返回if(字符串长度($string)<8)
>然后bs:检查是否有八个(concat($string,0))
>else$string(:作为私有添加到下面:)
>**返回bs:concat字符串($fullBinary)**};
尽管上面是关键字,$fullBinary变量在一个循环中,产生了空的空格(?),当我使用X作为分隔符时,它清晰地显示出来。 免责声明:我之前考虑过这一点,并使用了functx:trim,但由于某些原因,它的工作方式与我预期的不一样。因此,如果出现类似问题,您可能也不会这么做


在这一点上很明显,让$fullBinary不能在FLWR语句中等待,至少不能触发concat strings函数。我改变了它,现在它只生成字符串,现在我试图找出运行整个模块的新顺序,但我认为这里的主要问题已经解决了。

好的,所以我想我找到了它

首先,在函数concat-strings中,我将concat改为fn:string-join。它允许我作为分隔连接字符串的参数符号进行传递

我看到我的输入是这样的: XXXXXXXX 010000111XXXXXXXXXXXXXXXXXXXXXXXXXXXX00110000XXXXXXXXXXXXXXXXXXXXXXXX001110100XXXXXXXXXXXX

显然,它必须在没有clear for loop的地方循环,作为Xquery的新手,我一定错过了这一点。事实上,我在检查8个函数时发现了它:

>声明函数bs:检查是否有八个($strings as item()+){
>**让$fullBinary:=**
>对于$string中的$string
>返回if(字符串长度($string)<8)
>然后bs:检查是否有八个(concat($string,0))
>else$string(:作为私有添加到下面:)
>**返回bs:concat字符串($fullBinary)**};
尽管上面是关键字,$fullBinary变量在一个循环中,产生了空的空格(?),当我使用X作为分隔符时,它清晰地显示出来。 免责声明:我之前考虑过这一点,并使用了functx:trim,但由于某些原因,它的工作方式与我预期的不一样。因此,如果出现类似问题,您可能也不会这么做


此时很明显,FLWR语句中不能使用let$fullBinary,至少不能触发concat strings函数。我更改了它,现在它只生成字符串,现在我试图找出运行整个模块的新顺序,但我认为这里的主要问题已经解决。

考虑包含最小样本输入和输出daTA(你想要的和当前的结果)在你的帖子中演示这个问题。你用其他XQuery处理器尝试过代码吗?谢谢你的建议。我上传了整个模块到那个点。我没有试着用其他XQuery处理器来运行它。它必须在BASEX中完成。考虑到包括最小的输入和输出数据。(通缉和当前结果)在您的帖子中演示该问题。您是否在其他XQuery处理器上尝试过该代码?谢谢您的建议。我确实上传了整个模块到了这一点。我没有尝试在其他XQuery处理器上运行此代码。它必须在basex中完成。
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")
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)  } ;
>  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)**  } ;