File: xml_cut.xml

package info (click to toggle)
virtuoso-opensource 7.2.5.1%2Bdfsg1-0.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 285,240 kB
  • sloc: ansic: 641,220; sql: 490,413; xml: 269,570; java: 83,893; javascript: 79,900; cpp: 36,927; sh: 31,653; cs: 25,702; php: 12,690; yacc: 10,227; lex: 7,601; makefile: 7,129; jsp: 4,523; awk: 1,697; perl: 1,013; ruby: 1,003; python: 326
file content (150 lines) | stat: -rw-r--r-- 5,640 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 -  
 -  This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
 -  project.
 -  
 -  Copyright (C) 1998-2018 OpenLink Software
 -  
 -  This project is free software; you can redistribute it and/or modify it
 -  under the terms of the GNU General Public License as published by the
 -  Free Software Foundation; only version 2 of the License, dated June 1991.
 -  
 -  This program is distributed in the hope that it will be useful, but
 -  WITHOUT ANY WARRANTY; without even the implied warranty of
 -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 -  General Public License for more details.
 -  
 -  You should have received a copy of the GNU General Public License along
 -  with this program; if not, write to the Free Software Foundation, Inc.,
 -  51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 -  
 -  
-->
<refentry id="fn_xml_cut">
  <refmeta>
    <refentrytitle>xml_cut</refentrytitle>
    <refmiscinfo>xml</refmiscinfo>
  </refmeta>
  <refnamediv>
    <refname>xml_cut</refname>
    <refpurpose>creates a new XML document which contains a copy of data pointed by given XML tree- or XPER- entity</refpurpose>
  </refnamediv>
  <refsynopsisdiv>
    <funcsynopsis id="fsyn_ml_cut">
      <funcprototype id="fproto_xml_cut">
        <funcdef><function>xml_cut</function></funcdef>
        <paramdef>in <parameter>source_entity</parameter> any (XML entity)</paramdef>
      </funcprototype>
    </funcsynopsis>
  </refsynopsisdiv>
  <refsect1 id="desc"><title>Description</title>
		<para>
In some special cases, some part of XML document,
being pointed by a XML entity, should be copied into a new separate document
with new entity pointing to the top-level element or the root of this document.
One reason for doing this is optimization of XPER processing (see <link linkend="fn_xper_cut">xper_cut</link>).
Another way to use this functionality is passing of some XML entity
to a function, when function uses XPath operations with references to
the &quot;document's root&quot;.
		</para>
    <example id="ex_xml_cut"><title>A sample of hidden bug</title>
      <para></para>
      <screen>
create procedure get_C (inout b any)
{
  return cast (xpath_eval('//C', b) as varchar);
}

create procedure hidden_bug_1()
{
  declare abc any;	-- some XML document
  declare b_list any;	-- a vector of all B elements of the doc
  declare c1 varchar;	-- a name of first variable
  declare c2 varchar;	-- a title of second variable
  abc := xtree_doc ('&lt;A&gt;&lt;B id="1"&gt;&lt;C&gt;One&lt;/C&gt;&lt;/B&gt;&lt;B id="2"&gt;&lt;C&gt;Two&lt;/C&gt;&lt;/B&gt;&lt;/A&gt;');
  b_list := xpath_eval ('//B', abc, 0);
  -- now b_list is a vector of two items, '&lt;B id="1"&gt;&lt;C&gt;One&lt;/C&gt;&lt;/B&gt;' and '&lt;B id="2"&gt;&lt;C&gt;Two&lt;/C&gt;&lt;/B&gt;'.
  c1 := get_C ( aref (b_list, 0));
  -- looks fine, c1 is '&lt;C&gt;One&lt;/C&gt;'
  c2 := get_C ( aref (b_list, 1));
  -- looks strange fine, c2 is '&lt;C&gt;One&lt;/C&gt;',
  -- while the expected value is '&lt;C&gt;Two&lt;/C&gt;'.
}
      </screen>
      <para>
The origin of the bug is '//C' path in get_C(), which returns not
the "C element inside given b element", but
"C element inside the document where given b element is located",
thus get_C returns the first C element in the whole document with any of
two B elements given.
      </para>
      <para>
There are two ways to fix this bug.
It is better to correct get_C():
      </para>
      <screen>
create procedure get_C (inout b any)
{
  return cast (xpath_eval('./C', b) as varchar);
}
      </screen>
      <para>
If you cannot patch get_C() for some reason, xml_cut will help,
but it will waste both memory and CPU time for copying a branch of
XML tree:
      </para>
      <screen>
create procedure hidden_bug_1()
{
...
  c1 := get_C ( xml_cut (aref (b_list, 0)));
...
}
      </screen>
    </example>
      <para>
The current node of the resulting entity is the node that is a copy
of the current node of the source entity. In common,
the top-level node of the copied subtree becomes the current node of the result.
There are two special cases, however. If the source entity is an attribute entity,
then the result is also an attribute entity and the attribute name remains the same.
If the source entity points to the root of the document, the resulting entity
also points to the root of the copied document, not to its top-level node.
      </para>
      <para>
With XPER entity given, xml_cut() works exactly as xper_cut().
      </para>
  </refsect1>
  <refsect1 id="params"><title>Parameters</title>
    <refsect2><title>source_xper</title>
      <para>XML Entity to be converted into new document</para></refsect2>
  </refsect1>
<!--
  <refsect1 id="ret"><title>Return Types</title><para></para></refsect1>
  <refsect1 id="errors"><title>Errors</title>
    <table><title>Errors signalled by</title>
      <tgroup cols="4">
       <thead><row><entry>SQLState</entry><entry>Error Code</entry><entry>Error Text</entry><entry>Description</entry></row></thead>
	<tbody>
	  <row>
	    <entry><errorcode></errorcode></entry>
	    <entry><errorcode></errorcode></entry>
	    <entry><errorname></errorname></entry>
	    <entry></entry>
	  </row>
	</tbody>
      </tgroup>
    </table>
  </refsect1>
  <refsect1 id="examples"><title>Examples</title>
    <example id="ex_"><title></title>
      <para></para>
      <screen></screen>
    </example>
  </refsect1>
-->
  <refsect1 id="seealso"><title>See Also</title>
    <para><link linkend="fn_xper_cut"><function>xper_cut()</function></link></para>
  </refsect1>
</refentry>