Solved

Need help with SQL and XML

Posted on 2014-03-20
7
232 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 16

Expert Comment

by:HooKooDooKu
ID: 39942256
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 32

Expert Comment

by:awking00
ID: 39943508
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
ID: 39944079
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
Free eBook: Backup on AWS

Everything you need to know about backup and disaster recovery with AWS, for FREE!

 
LVL 1

Author Comment

by:yechan
ID: 39944904
@ 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
ID: 39945025
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
ID: 39945080
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
ID: 39945083
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

Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows gives you an overview on SQL Server 2016 row level security. You will also get to know the usages of row-level-security and how it works
In the first part of this tutorial we will cover the prerequisites for installing SQL Server vNext on Linux.
Via a live example, show how to shrink a transaction log file down to a reasonable size.
Viewers will learn how to use the UPDATE and DELETE statements to change or remove existing data from their tables. Make a table: Update a specific column given a specific row using the UPDATE statement: Remove a set of values using the DELETE s…

695 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