I have a task of parsing a simple XML-formatted string in a MySQL stored procedure. XML looks like this (testing purposes only):
<parent>
<child>Example 1</child>
<child>Example 2</child>
</parent>
What I need MySQL to do is to produce a result set one row per match. My stored proc code looks like this:
DECLARE xmlDoc TEXT;
SET xmlDoc = '<parent><child>Example 1</child><child>Example 2</child></parent>';
SELECT ExtractValue(xmlDoc, '//child');
What this does, however, is it concatenate all the matches, producing "Example 1 Example 2". This is, by the way, documented, but quite useless behavior.
What can I do to make it return the matches in rows without having to count the matches and processing them one-by-one? Is it even possible with MySQL?
Thanks all!
XML SupportAurora MySQL supports two XML functions: ExtractValue and UpdateXML . ExtractValue accepts an XML document, or fragment, and an XPATH expression. The function returns the character data of the child or element matched by the XPATH expression.
To import data from a XML file into a MySQL table, select the table in Object Browser and select Table -> Import -> Import XML Data Using Load Local... or(Ctrl+Shift+X). Tables: The list of all tables of the currently active database is shown. Select the Table from the list box.
The most common way to store XML in MySQL is to use the LOAD_FILE() function to open an entire XML document, store it in a variable, and insert the variable into a table column.
You can use XML from within any language that has the appropriate processing tools available. For example, XML APIs exist for languages such as PHP, Python, Java, and Tcl, all of which also have MySQL capabilities.
This needs a rowset generation function, and MySQL
lacks it.
You can use a dummy table or a subquery instead:
SELECT ExtractValue(@xml, '//mychild[$@r]'),
@r := @r + 1
FROM (
SELECT @r := 1
UNION ALL
SELECT 1
) vars
Note that support for session variables in XPath
is broken in 5.2
(but works fine in 5.1
)
DECLARE i INT DEFAULT 1;
DECLARE count DEFAULT ExtractValue(xml, 'count(//child)');
WHILE i <= count DO
SELECT ExtractValue(xml, '//child[$i]');
SET i = i+1;
END WHILE
Alternatively...
DECLARE v VARCHAR(500) DEFAULT '';
DECLARE i INT DEFAULT 1;
REPEAT
SET v = ExtractValue(xml, '//child[$i]')
SET i = i+1;
IF v IS NOT NULL THEN
-- do something with v
END IF
UNTIL v IS NULL
Sorry if the syntax is a bit shakey in here, not much of a mysql guru...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With