This discussion is archived
2 Replies Latest reply: Aug 24, 2011 5:46 AM by 883286 RSS

XPath String Expression Evaluation Using Variable

883286 Newbie
Currently Being Moderated
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
PL/SQL Release 11.2.0.2.0 - Production
CORE     11.2.0.2.0     Production
TNS for 32-bit Windows: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

5 rows selected.

SQL> get &xdb.eval
1 xquery
2 let $x := document { <doc><a>1</a><b>2</b><c>3</c></doc> }
3 let $i := "/doc/a"
4* return $x (: { $i } :)
SQL> /

Result Sequence
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<doc><a>1</a><b>2</b><c>3</c></doc>

1 item(s) selected.

SQL> edit
Wrote file afiedt.buf

1 xquery
2 let $x := document { <doc><a>1</a><b>2</b><c>3</c></doc> }
3 let $i := "/doc/a"
4* return $x { $i }
SQL> /
ERROR:
ORA-19114: XPST0003 - error during parsing the XQuery expression:
LPX-00801: XQuery syntax error at '{'
3 return $x { $i }
- ^


SQL> -- expected result: <a>1</a>

My objective is to utilize results from xmldiff function to analyze changes in xml documents. The xmldiff produces update-node elements with an xpath attribute. I want to produce an expanded result with surrounding elements of the nodes changed. This feature of evaluating the contents of a variable in UNIX is provided by $(expr) or eval function in other scripting languages. How is this done in xquery?

Edited by: 880283 on Aug 18, 2011 7:26 PM
  • 1. Re: XPath String Expression Evaluation Using Variable
    odie_63 Guru
    Currently Being Moderated
    Hi,

    There's no standard XQuery function to do that.

    Here are some alternatives :

    1- building the whole XQuery expression dynamically
    2- using a user-defined function to access the elements addressed by the XPath expression
    3- using extract function, but it's deprecated...

    Example of 1-
    SQL> var doc1 varchar2(4000)
    SQL> var doc2 varchar2(4000)
    
    SQL> begin
      2  
      3   :doc1 := '<root>
      4   <item id="1">
      5    <subitem>ABC</subitem>
      6    <subitem>XYZ</subitem>
      7   </item>
      8  </root>';
      9  
     10   :doc2 := '<root>
     11   <item>
     12    <subitem>ABC</subitem>
     13    <subitem>XYZ</subitem>
     14   </item>
     15   <item id="2">
     16    <subitem>123</subitem>
     17   </item>
     18  </root>';
     19  
     20  end;
     21  /
     
    PL/SQL procedure successfully completed
     
    SQL> with t as (
      2   select xmldiff(xmltype(:doc1), xmltype(:doc2)) xdiff_doc
      3   from dual
      4  )
      5  select x.*,
      6         xmlserialize(document
      7           xmlquery(x.parent_xpath
      8             passing xmltype(:doc1)
      9             returning content
     10           )
     11           as clob indent
     12         ) parent_node
     13  from t,
     14       xmltable(
     15         xmlnamespaces('http://xmlns.oracle.com/xdb/xdiff.xsd' as "xd"),
     16         '/xd:xdiff/child::*'
     17         passing t.xdiff_doc
     18         columns
     19           op_type        varchar2(30)   path 'local-name(.)'
     20         , node_type      varchar2(30)   path '@xd:node-type'
     21         , parent_xpath   varchar2(2000) path '@xd:parent-xpath'
     22         , attribute_name varchar2(30)   path '@xd:attr-local'
     23       ) x
     24  ;
     
    OP_TYPE                        NODE_TYPE                      PARENT_XPATH                 ATTRIBUTE_NAME                 PARENT_NODE
    ------------------------------ ------------------------------ ---------------------------- ------------------------------ ----------------------------------
    delete-node                    attribute                      /root[1]/item[1]             id                             <item id="1">
                                                                                                                                <subitem>ABC</subitem>
                                                                                                                                <subitem>XYZ</subitem>
                                                                                                                              </item>
     
    append-node                    element                        /root[1]                                                    <root>
                                                                                                                                <item id="1">
                                                                                                                                  <subitem>ABC</subitem>
                                                                                                                                  <subitem>XYZ</subitem>
                                                                                                                                </item>
                                                                                                                              </root>
     
    Edited by: odie_63 on 19 août 2011 10:40
  • 2. Re: XPath String Expression Evaluation Using Variable
    883286 Newbie
    Currently Being Moderated
    Greetings,
    Your example of alternative #1 is a viable solution and I have already begun some initial testing using this approach. I greatly appreciate an example that demonstrated use of XMLDIFF results as this is directly related to my objectives.

    I would be interested in obtaining some additional details and possibly an example of using alternative #2 (User Defined Function) to accomplish this task.

    best Regards

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points