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 "document's root".
</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 ('<A><B id="1"><C>One</C></B><B id="2"><C>Two</C></B></A>');
b_list := xpath_eval ('//B', abc, 0);
-- now b_list is a vector of two items, '<B id="1"><C>One</C></B>' and '<B id="2"><C>Two</C></B>'.
c1 := get_C ( aref (b_list, 0));
-- looks fine, c1 is '<C>One</C>'
c2 := get_C ( aref (b_list, 1));
-- looks strange fine, c2 is '<C>One</C>',
-- while the expected value is '<C>Two</C>'.
}
</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>
|