Xml 如何声明XQuery 1.0 while循环以通过追加字符生成字符串
在我的XQuery 1.0文件中,我有一个字符串作为输入,其格式与xsd:duration元素PnYnMnDTnHnMnS相同。其中P是强制性的,n是年数、月数等,T是小时数、分钟数等的分隔符 我的输入是一个字符串,可能不完整,我的意思是,年,月。。。“分钟”字段无法显示。然后,我的输出必须是一个完整的duration元素,其中缺少的字段必须用0填充 例如: P1YT1H2M50S-->P1Y0M0DT1H2M50S 我的问题是,我不知道用局部变量正确编写while循环的语法 注意:此代码不编译。这只是伪代码 我是XQuery新手,不知道正确的sintax。我的想法是迭代字符串,检查缺少的字段,并将部分结果附加到将返回的变量Xml 如何声明XQuery 1.0 while循环以通过追加字符生成字符串,xml,string,while-loop,xquery,transformation,Xml,String,While Loop,Xquery,Transformation,在我的XQuery 1.0文件中,我有一个字符串作为输入,其格式与xsd:duration元素PnYnMnDTnHnMnS相同。其中P是强制性的,n是年数、月数等,T是小时数、分钟数等的分隔符 我的输入是一个字符串,可能不完整,我的意思是,年,月。。。“分钟”字段无法显示。然后,我的输出必须是一个完整的duration元素,其中缺少的字段必须用0填充 例如: P1YT1H2M50S-->P1Y0M0DT1H2M50S 我的问题是,我不知道用局部变量正确编写while循环的语法 注意:此代码不编译
<typ:validityPeriod>
{
let $input := 'P1YT1H2M50S'
let $index := 2
let $result := 'P'
let $Y_read := false
let $Months_read := false
let $D_read := false
let $T_read := false
let $H_read := false
let $Minutes_read := false
let $S_read := false
let $acu := ''
while (not($S_read)){
let $char := xs:substring($input, $index,$index)
if ($char = 'Y') then
$Y_read := true
$result := fn:concat($result, $acu, 'Y')
$acu := ''
else if ($char = 'M') then
if (not($T_read)) then
$Months_read := true
if ($Y_read) then
$result := fn:concat($result, $acu, 'M')
else
$result := fn:concat($result, '0Y', $acu, 'M')
else
$Minutes_read := true
if (not($H_read)) then
$result := fn:concat($result, 'T0H')
$result := fn:concat($result, $acu, 'M')
$acu := ''
else if ($char = 'D')
$D_read := true
if (not($Y_read)) then
$result := fn:concat($result, '0Y')
if (not($Months_read)) then
$result := fn:concat($result, '0M')
$result := fn:concat($result, $acu, 'D')
$acu := ''
else if ($char = 'T') then
$acu := ''
if (not($Y_read)) then
$result := fn:concat($result, '0Y')
if (not($Months_read)) then
$result := fn:concat($result, '0M')
if (not($D_read)) then
$result := fn:concat($result, '0D')
$T_read = true
$acu := ''
else if ($char = 'H')
$H_read := true
$acu := ''
<the same logic>
else if ($char = 'S')
<the same logic>
$S_read := true
else
$acu := fn:concat($acu, $char)
$index := $index + 1
}
return xs:duration($result)
}
</typ:validityPeriod>
我认为这应该给出正确的答案:
let $d := xs:duration('P1YT1H2M50S')
return concat('P',
years-from-duration($d), 'Y',
months-from-duration($d), 'M',
days-from-duration($d), 'D',
'T',
hours-from-duration($d), 'H',
minutes-from-duration($d), 'M',
seconds-from-duration($d), 'S')
XQuery没有while语句。也不是可变变量。您需要为每个字母编写一个单独的let语句,或者编写一个递归函数。然而,你到底想做什么?持续时间可以处理丢失的字母。xs:durationP1YT1H2M50S返回持续时间。同样的持续时间。xs:durationP1Y0M0DT1H2M50S=xs:durationP1YT1H2M50S您不能单独告诉他们输出的规格说明输出必须显示所有字母。但是我发现了一种更好的使用正则表达式的方法。替换$input,P[0-9]+Y?[0-9]+M?[0-9]+D?T[0-9]+H?[0-9]+M?[0-9]+S??,P$2Y$4M$6DT$9H$1100万$13S[A-Za-z][A-SU A-Za-SU-z][A-SU A-Za Za z][A-Za A-Za SU-Za SU-SU-z],$10$2你已经把它写成了非常程序化的伪代码。将过程代码逆向工程为声明性代码并不容易;你真的需要试着用一种更具陈述性的方式来思考。