Solved

Need help with SQL and XML

Posted on 2014-03-20
7
229 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
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)

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Why is this different from all of the other step by step guides?  Because I make a living as a DBA and not as a writer and I lived through this experience. Defining the name: When I talk to people they say different names on this subject stuff l…
How to leverage one TLS certificate to encrypt Microsoft SQL traffic and Remote Desktop Services, versus creating multiple tickets for the same server.
Via a live example, show how to extract information from SQL Server on Database, Connection and Server properties
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.

756 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