Проблема с рекурсивной функцией xquery - PullRequest
0 голосов
/ 21 сентября 2018

У меня возникли трудности с созданием рекурсивной функции, которую я написал.Мне нужно иметь возможность превратить этот xml:

<entry ref="22">
    <headword>abaishen</headword>
    <part_of_speech> v. </part_of_speech>
    <variant>abeishen</variant>
    <variant>abaissen</variant>
    <variant>abeisen</variant>
    <variant>abashen</variant>
    <variant>abasshen</variant>
    <variant>abassen</variant>
    <variant>abeeshen</variant>
    <variant>abesen</variant>
    <variant>abessen</variant>
    <variant>abaished</variant>
    <variant>-et</variant>
    <variant>-it</variant>
    <variant>abaisht</variant>
    <variant>abaist</variant>
    <variant>abasht</variant>
    <variant>abast</variant>
</entry>

в этот XML - по сути, заменяя окончание любой записи, начинающейся с «-», основанием последней полной записи:

 <entry ref="22">
        <headword>abaishen</headword>
        <variant>abeishen</variant>
        <variant>abaissen</variant>
        <variant>abeisen</variant>
        <variant>abashen</variant>
        <variant>abasshen</variant>
        <variant>abassen</variant>
        <variant>abeeshen</variant>
        <variant>abesen</variant>
        <variant>abessen</variant>
        <variant>abaished</variant>
        <variant>abaishet</variant>
        <variant>abaishit</variant>
        <variant>abaisht</variant>
        <variant>abaist</variant>
        <variant>abasht</variant>
        <variant>abast</variant>
        <part_of_speech> v. </part_of_speech>
    </entry>

Проблема, с которой я сталкиваюсь, заключается в том, что вторая запись, -it, возвращает "abaishet" с кодом, который у меня сейчас есть:

declare function local:hyphen-replace($f) {
let $j :=
   if (substring($f/text(), 1, 1) = "-") then
      let $ending := substring-after($f/text(),"-")
      let $ending-length := string-length($ending)
      let $previous := $f/preceding-sibling::*[1]
      let $previous-length := string-length($previous)
      return
           if (substring($previous/text(), 1, 1) = "-") then
               local:hyphen-replace($previous)
           else
               element {name($f)} {concat(substring($previous,1,($previous-length - $ending-length)),$ending)}   
 else
     $f
return $j
};

declare function local:verbCheck($nodes as node()*) as node()* {

    let $d := $nodes/part_of_speech
    let $s := functx:siblings($d)
    let $p := for $node in $nodes
                return
                    let $d := $node/part_of_speech
                    let $s := functx:siblings($d)
                    return
                        if ($d/text() = " v. ") then
                            for $f in $s
                                let $j := 
                                    local:hyphen-replace($f)
                            return ($j)


                        else
                            <empty/>

    return
      ($p,$d)
};

<list>
    {

        let $collection := concat($collection, '?select=*.xml')
        let $q := collection($collection)
        let $v := local:buildNodes($q)

        let $entries := 
            for $n in $v
            return <entry ref="{$n/@ref}">{local:verbCheck($n)}</entry>

        return local:remove-empty-elements($entries)

    }
</list>

Для меня очевидно, что моя проблемас этим фрагментом кода в local:hypen-replace:

if (substring($previous/text(), 1, 1) = "-") then
                   local:hyphen-replace($previous)

, потому что он вызывает непосредственно предыдущий элемент и заменяет узел "-it" его информацией.Но я не знаю, как переписать его, чтобы он работал рекурсивно правильно.Мы ценим любые предложения.Спасибо.

...