4 Replies Latest reply: Mar 22, 2013 2:57 PM by KnightOfBlueArmor RSS

    XQJ API and updating functions

    KnightOfBlueArmor
      Forgive me if I've cross-posted this; I didn't know whether to put this in the XML DB forum or here.

      I have the following XQuery code which is intended to merge two XML documents together, except for the SUMM element which follows special rules.

      When I run this code through XQJ using the xqjqpi/xqjori version 11.2.0.3 JAR's, I receive the error "oracle.xquery.xqj.OXQException: XPST0003: It is a static error if an expression is not a valid instance of the grammar defined in A.1 EBNF." Did I get the XQuery code wrong, or does XQJ not support updating functions at this point?
      declare namespace myns="http://www.customer.com/myns";
      declare namespace subns="http://www.customer.com/myns/subns";
      declare namespace mycomp="http://www.mycompany.com";
      
      declare updating function mycomp:summ_merge($old, $summ)
      {
           for $entr in $summ/subns:ENTR
           let $chgCd := $entr/subns:CHG_CD
           let $incDateYrMo := $entr[DATA_INC_DT]
           let $oldEntr := $old/subns:SUMM/subns:ENTR[DATA_INC_DT=$incDateYrMo]
           return
              if( $chgCd = '399' and count($oldEntr) = 1 )
              then delete node $oldEntr
              else if( $chgCd = '399' )
              then fn:trace($entr, 'This node was ignored because it had a CHG_CD of 399, but there was no corresponding ENTR: ')
              else if( count($oldEntr) = 1 )
              then replace node $oldEntr with $entr
              else insert node $oldEntr into $summ
      };
      
      declare updating function mycomp:summ_update($old, $summ)
      {
           let $chgCd := $summ/subns:CHG_CD;
           return
              if( $chgCd = '600' )
              then delete node $old/subns:SUMM/*
              else mycomp:summ_merge($old, $summ)
      };
      
      
      copy $olddoc := $orig
           
      modify
      (
          for $new in $newdoc//myns:PAYLOAD/*
                let $allNew := $newdoc//myns:PAYLOAD/*[name()=name($new)]
                let $old := $olddoc//myns:PAYLOAD
                let $match := $olddoc//myns:PAYLOAD/*[name()=name($new)]
                let $name := name($new)
      return
        if ( local-name($new) = 'SUMM' and count($match) = 1 )
        then mycomp:summ_update($old, $new)
        else if ( local-name($new) = 'SUMM' and count($match) = 0 )
        then insert node $new into $olddoc/myns:PAYLOAD
        else if ( exists($match) and count($match) = 1 and count($allNew) = 1 )
        then replace node $match with $new
        else insert node $new into $old
      ) return $olddoc