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>.
