Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Need help with SQL and XML

Posted on 2014-03-20
7
Medium Priority
?
237 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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 2000 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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

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
One of the most important things in an application is the query performance. This article intends to give you good tips to improve the performance of your queries.
Via a live example combined with referencing Books Online, show some of the information that can be extracted from the Catalog Views in SQL Server.
Viewers will learn how to use the SELECT statement in SQL and will be exposed to the many uses the SELECT statement has.

610 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