Following up from: Is this XML format correct?
I’ve got some SQL code working that loops through the QABLOCKs and prints them (the PRINTs will change to INSERTs in production).
-- XML instance
DECLARE @x1 XML
SELECT @x1 =
'
<tests>
<test id="1">
<qablock number="1">
<question>What is 1 + 1?</question>
<explanation>It"s 2.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="1" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="0" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
<qablock number="2">
<question>What is 2 + 2?</question>
<explanation>It"s 4.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="0" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="1" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
</test>
</tests>
'
DECLARE
@cnt INT,
@totCnt INT,
@child XML
-- counter variables
SELECT
@cnt = 1,
@totCnt = @x1.value('count(/tests/test/qablock)','INT')
-- loop
WHILE @cnt <= @totCnt BEGIN
SELECT
1 AS tests_id, --this is hard-coded
@cnt AS qablock_number,
@x1.value('(/tests/test/qablock[position()=sql:variable("@cnt")]/question/text())[1]','varchar(500)') AS question,
@x1.value('(/tests/test/qablock[position()=sql:variable("@cnt")]/explanation/text())[1]','varchar(1000)') AS explanation
PRINT 'Processing Child Element: ' + CAST(@cnt AS VARCHAR)
PRINT 'Child element: ' + CAST(@child AS VARCHAR(max))
PRINT ''
-- increment the counter variable
SELECT @cnt = @cnt + 1
END
I don’t know if that’s the correct procedure whatsoever, but at least it seems to work. What I’d like to do next is run another similar script that loops through all the OPTIONs and PRINTs them as well. For each OPTION, I need to print: QABLOCK number, OPTION number, OPTION value, and OPTION is_correct. I can’t even get close. 🙁 Here’s what I’ve got so far:
-- XML instance
DECLARE @x1 XML
SELECT @x1 =
'
<tests>
<test id="1">
<qablock number="1">
<question>What is 1 + 1?</question>
<explanation>It"s 2.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="1" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="0" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
<qablock number="2">
<question>What is 2 + 2?</question>
<explanation>It"s 4.</explanation>
<options>
<option number="1" value="1" correct="0" />
<option number="2" value="2" correct="0" />
<option number="3" value="3" correct="0" />
<option number="4" value="4" correct="1" />
<option number="5" value="5" correct="0" />
</options>
</qablock>
</test>
</tests>
'
DECLARE
@cnt INT,
@totCnt INT,
@child XML
-- counter variables
SELECT
@cnt = 1,
@totCnt = @x1.value('count(/tests/test/qablock/options/option)','INT')
-- loop
WHILE @cnt <= @totCnt BEGIN
SELECT
1 AS tests_id, --hard-coded value
@x1.value('(/tests/test/qablock/@number)[1]','varchar(500)') AS qablock_number,
@x1.value('(/tests/test/qablock/options/option[position()=sql:variable("@cnt")]/@number)[1]','varchar(500)') AS option_number
PRINT 'Processing Child Element: ' + CAST(@cnt AS VARCHAR)
PRINT 'Child element: ' + CAST(@child AS VARCHAR(max))
PRINT ''
-- increment the counter variable
SELECT @cnt = @cnt + 1
END
So, obviously it’s messed up, but I can’t seem to figure out what to change.
First of all, I don’t know how to get the parent QABLOCK number of the current OPTION.
Second, only my first 5 option_number’s are displaying their numbers properly, the second 5 are showing NULL.
P.S. Some of this code was from:
http://beyondrelational.com/modules/2/blogs/28/posts/10316/xquery-lab-35-how-to-write-a-loop-to-process-all-the-child-elements-of-an-xml-value.aspx
This should do the trick:
Or better still (thanks to the link you provided for prompting me):