0

そのため、ノイズの多い xml 入力データがあり、すべてが日付であるため、それを xs:gYear にキャストしたいと考えています。

let $dates := 
<date>
    <a>-1234</a>
    <b/>    
    <c>1911</c> 
    <d>786</d>
    <e>-90</e>
    <f>0</f>
    <g>0302</g>
    <h>-0987</h>
</date>

最初に考えたのは、次のようにキャストを使用しましょう:

for $n in $dates/*
return if ($n castable as xs:gYear) then ($n cast as xs:gYear) 
else ("boo")

これは、有効な gYear ints を xs:gYear として返しますが、私が望んでいたものではありません:

declare function local:isodate ($string as xs:string)  as xs:string* {
        if (empty($string)) then ()
        else if (starts-with($string, "-")) then (concat('-',(concat (string-join((for $i in (string-length(substring($string,2)) to 3) return '0'),'') , substring($string,2)))))
        else (concat (string-join((for $i in (string-length($string) to 3) return '0'),'') , $string))
    };
   return local:isodate("-1234 ,'', 1911, 786, -90, 0, 0302, -0987")

年「0」を除いて機能します。0000 も有効な年ではなく、データには過去の日付が含まれていますが、ユリウス暦や年 0 を含むその他の形式ではないため、"" を返すにはどうすればよいですか。

実際に 123 を 0123 に変換する必要があるように、私の最初のアイデアは軌道に乗っていましたか、そうでしたか?

4

2 に答える 2

1

このようなものはどうですか?

declare function local:as-year($year as xs:string) as xs:gYear? {
    let $y := number($year)
    return
        if($y lt 0)then
            concat("-", substring(string(10000 + $y * -1), 2)) cast as xs:gYear
        else if($y gt 0)then
            substring(string(10000 + $y), 2) cast as xs:gYear
        else()
};


let $dates := 
    <date>
        <a>-1234</a>
        <b/>    
        <c>1911</c> 
        <d>786</d>
        <e>-90</e>
        <f>0</f>
        <g>0302</g>
        <h>-0987</h>
    </date>
return
    for $n in $dates/*
    return   
        local:as-year($n)
于 2014-09-15T16:51:03.467 に答える