I tried this query in Workbench and wonder why the second update //b[2]
did not change?
SET @xml = '<a><b>111</b><b>222</b><b>333</b></a>';
SELECT
UpdateXML(@xml, '/a/b[1]',
Concat('<e>', Extractvalue(@xml,'//b[1]'),'</e>')) INTO @xml;
SELECT
UpdateXML(@xml, '/a/b[2]',
Concat('<e>', Extractvalue(@xml,'//b[2]'),'</e>')) INTO @xml;
SELECT
UpdateXML(@xml, '/a/b[3]',
Concat('<e>', Extractvalue(@xml,'//b[3]'),'</e>')) INTO @xml;
SELECT @xml
Here's the result:
----------------------------------------
| @xml |
----------------------------------------
|'<a><e>111</e><b>222</b><e>333</e></a>' |
----------------------------------------
The middle <b>222</b>
should supposed to be changed to <e>222</e>
. I've already checked every single letter in my code repeatedly.
Help please!...
CodePudding user response:
Your updates are always effectively replacing the first <b>
tag with an <e>
tag. Changes to @xml
are cumulative. I.e., each statement is receiving the value of @xml
updated by the previous statement.
Since you are mutating @xml
, you first statement will replace the first <b>
with an <e>
. After running the first statement, @xml
will look like this:
<a><e>111</e><b>222</b><b>333</b></a>
Your second statement will start with the above value and then seek and mutate the second <b>
that it can find (i.e., the last one in the sequence):
<a><e>111</e><b>222</b><e>333</e></a>
Finally you last statement will start with the value above and try to seek the third <b>
. Since there is only one <b>
left (the middle tag), the third statement does nothing.
Here's a working version:
SET @xml = '<a><b>111</b><b>222</b><b>333</b></a>';
SELECT
UpdateXML(@xml, '/a/b[1]',
Concat('<e>', Extractvalue(@xml,'//b[1]'),'</e>')) INTO @xml;
SELECT
UpdateXML(@xml, '/a/b[1]',
Concat('<e>', Extractvalue(@xml,'//b[1]'),'</e>')) INTO @xml;
SELECT
UpdateXML(@xml, '/a/b[1]',
Concat('<e>', Extractvalue(@xml,'//b[1]'),'</e>')) INTO @xml;
SELECT @xml
In the version above, the code is always replacing the first <b>
in @xml
. Here's how the value of XML is updated:
- After the 1st statement:
<a><e>111</e><b>222</b><b>333</b></a>
- After the 2nd statement: `111222333
- After the 3rd statement:
<a><e>111</e><e>222</e><e>333</e></a>
.