Solved

Need help with SQL and XML

Posted on 2014-03-20
7
224 Views
Last Modified: 2014-03-21
Hi,

I need some help on how to extract the values of XML elements.  The XML is formatted as follows:

declare @myxml as xml = '
<table class="genTbl closedTbl historicalTbl" id="curr_table">
	<thead>
		<tr>
			<th class="first left noWrap">Date</th>
			<th class="noWrap">Last</th>
			<th class="noWrap">Open</th>
			<th class="noWrap">High</th>
			<th class="noWrap">Low</th>
			<th class="noWrap">Change</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td class="first left bold noWrap">Mar 19, 2014</td>
			<td class="redFont">3674.30</td>
			<td>3697.60</td>
			<td>3705.20</td>
			<td>3652.90</td>
			<td class="bold redFont">-0.62%</td>
		</tr>
		<tr>
			<td class="first left bold noWrap">Mar 18, 2014</td>
			<td class="greenFont">3697.20</td>
			<td>3652.70</td>
			<td>3701.90</td>
			<td>3639.90</td>
			<td class="bold greenFont">1.22%</td>
		</tr>
		<tr>
			<td class="first left bold noWrap">Mar 17, 2014</td>
			<td class="greenFont">3652.80</td>
			<td>3614.60</td>
			<td>3672.70</td>
			<td>3613.20</td>
			<td class="bold greenFont">1.07%</td>
		</tr>
	</tbody>
</table>'

Open in new window


How can I extract the data so it looks something like the following:

Date            Last            Open            High            Low                  Change
3/19/14      3674.30      3697.60            3705.20      3652.90            -0.62
etc.

thanks
0
Comment
Question by:yechan
7 Comments
 
LVL 16

Expert Comment

by:HooKooDooKu
Comment Utility
To the best of my knowledge, XML is not a database, and therefore you can not use SQL to get anything out of an XML file.  Instead, you need an XML parser engine that accepts XPath statements... which are sort of like a query language for XML.

So if I were attempting to accomplish this, I would be starting with downloading MSXML 6.0:
http://www.microsoft.com/en-us/download/details.aspx?id=3988

Of course MSXML 6.0 is over 5 years old... so there might have been something else that has come along since I worked with SML that might allow SQL to access an XML file... but if so, I'm not aware of it.
0
 
LVL 31

Expert Comment

by:awking00
Comment Utility
This appears to define an HTML table. Is it stored as an xml column in a sql server database?
0
 
LVL 75

Expert Comment

by:Anthony Perkins
Comment Utility
You can use the SQL Server Xml Data Type Methods to retrieve the values.  For example if you wanted to get the first "class" attribute in the "thead" node you would do this;
SELECT @myxml.value('(table/thead/tr/th/@class)[1]', 'varchar(50)')
This returns:
first left noWrap
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 1

Author Comment

by:yechan
Comment Utility
@ awking00:

For right now, I was hoping to be able to extract the values from the @myxml variable.  If you think to store the data in a xml data column just to get things going, I am cool with that too.

@Anthony:
Using the value() to extract the value within an element (i.e. SELECT @myxml.value('(table/tbody/tr/td)[1]', 'varchar(50)') AS myDate) I can extract the value of the first element, but how can I get a set of data like so:

Date            Last            Open            High            Low                  Change
3/19/14      3674.30      3697.60        3705.20      3652.90            -0.62
3/18/14      3697.20      3652.70        3701.90      3639.90             1.22
etc.

thank you.
0
 
LVL 75

Expert Comment

by:Anthony Perkins
Comment Utility
You can use the nodes() method for that.  Let me know if you need an example.
0
 
LVL 75

Accepted Solution

by:
Anthony Perkins earned 500 total points
Comment Utility
Here you go (change the data types as appropriate):
SELECT  T.C.value('(td)[1]', 'date') [Date],
        T.C.value('(td)[2]', 'smallmoney') [Last],
        T.C.value('(td)[3]', 'smallmoney') [Open],
        T.C.value('(td)[4]', 'smallmoney') [High],
        T.C.value('(td)[5]', 'smallmoney') [Low],
        T.C.value('(td)[5]', 'smallmoney') [Change]
FROM    @myxml.nodes('table/tbody/tr') T (C)

Open in new window

0
 
LVL 1

Author Comment

by:yechan
Comment Utility
Thanks Anthony.  I think I got it to work.


SELECT
      T.c.query('td[1]/text()') AS MyDate,
      T.c.query('td[2]/text()') AS MyLast
      etc
FROM  
      @myxml.nodes('/table/tbody/tr') T(c)
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

How to leverage one TLS certificate to encrypt Microsoft SQL traffic and Remote Desktop Services, versus creating multiple tickets for the same server.
Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
Viewers will learn how the fundamental information of how to create a table.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now