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