Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

How to parse XML field in SQL Server 2008 R2

Posted on 2014-03-27
5
Medium Priority
?
6,834 Views
Last Modified: 2014-03-28
Hello, I'm trying to parse an XML field in a third party database and I haven't had any luck returning any of the individual elements.  I've been able to parse XML with nested tags before, but apparantly this is too complex.  

Specifically, I need to return all of the RiskCode, Description and Sequence values from the HighRiskIndicators section - but eventually I'll need to return all of the values.

I've attached a sample of the XML below.  Any and all help is greatly appreciated.
XML-Sample.txt
0
Comment
Question by:EasyNiner
  • 3
5 Comments
 
LVL 75

Accepted Solution

by:
Anthony Perkins earned 2000 total points
ID: 39960579
Try it this way:
;WITH XMLNAMESPACES ('http://webservices.seisint.com/WsIdentity'  AS WS)

SELECT	T.C.value('WS:RiskCode[1]', 'varchar(10)') RiskCode,	-- Change the data type as appropriate
	T.C.value('WS:Description[1]', 'varchar(100)') [Description],
	T.C.value('WS:Sequence[1]', 'varchar(100)') Sequence
FROM	YourTable
	CROSS APPLY X.nodes('InstantIDModelResponse/WS:Result/WS:Models/WS:Model/WS:Scores/WS:Score/WS:HighRiskIndicators/WS:HighRiskIndicator') T(C)

Open in new window

0
 
LVL 75

Expert Comment

by:Anthony Perkins
ID: 39960589
This is how I tested it:
DECLARE @YourTable TABLE (X Xml)
INSERT @YourTable(X) 
VALUES (
'<InstantIDModelResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Header xmlns="http://webservices.seisint.com/WsIdentity">
    <Status>0</Status>
    <QueryId>1234</QueryId>
    <TransactionId>1311111R700000</TransactionId>
  </Header>
  <Result xmlns="http://webservices.seisint.com/WsIdentity">
    <InputEcho>
      <Name>
        <First>TOM</First>
        <Last>SMITH</Last>
      </Name>
      <Address>
        <StreetAddress1>123 Main St</StreetAddress1>
        <City>DESOTO</City>
        <State>TX</State>
        <Zip5>75110</Zip5>
      </Address>
      <DOB>
        <Year>1980</Year>
        <Month>1</Month>
        <Day>15</Day>
      </DOB>
      <Age>34</Age>
      <SSN>123456789</SSN>
      <HomePhone>4697219454</HomePhone>
    </InputEcho>
    <Models>
      <Model>
        <Name>ConsumerVerificationIndex</Name>
        <Scores>
          <Score>
            <Type>nas</Type>
            <Value>8</Value>
            <HighRiskIndicators>
              <HighRiskIndicator>
                <RiskCode>03</RiskCode>
                <Description>The input SSN was issued prior to the input date-of-birth</Description>
                <Sequence>1</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>26</RiskCode>
                <Description>Unable to verify SSN/TIN</Description>
                <Sequence>2</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>27</RiskCode>
                <Description>Unable to verify phone number</Description>
                <Sequence>3</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>52</RiskCode>
                <Description>The input first name is not associated with input SSN</Description>
                <Sequence>4</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>10</RiskCode>
                <Description>The input phone number is a mobile number</Description>
                <Sequence>5</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>82</RiskCode>
                <Description>The input name and address return a different phone number</Description>
                <Sequence>6</Sequence>
              </HighRiskIndicator>
            </HighRiskIndicators>
          </Score>
        </Scores>
      </Model>
    </Models>
    <DOBVerified>true</DOBVerified>
  </Result>
</InstantIDModelResponse>')

;WITH XMLNAMESPACES ('http://webservices.seisint.com/WsIdentity'  AS WS)

SELECT	T.C.value('WS:RiskCode[1]', 'varchar(10)') RiskCode,		-- Change the data type as appropriate
	T.C.value('WS:Description[1]', 'varchar(100)') [Description],
	T.C.value('WS:Sequence[1]', 'varchar(100)') Sequence
FROM	@YourTable
	CROSS APPLY X.nodes('InstantIDModelResponse/WS:Result/WS:Models/WS:Model/WS:Scores/WS:Score/WS:HighRiskIndicators/WS:HighRiskIndicator') T(C)

Open in new window

Output :
03	The input SSN was issued prior to the input date-of-birth	1
26	Unable to verify SSN/TIN					2
27	Unable to verify phone number					3
52	The input first name is not associated with input SSN		4
10	The input phone number is a mobile number			5
82	The input name and address return a different phone number	6

Open in new window

0
 

Author Closing Comment

by:EasyNiner
ID: 39960666
That was exactly what I was looking for.  I thought I only had to use the namespace alias for the parent tag.  Thanks again!
0
 
LVL 13

Expert Comment

by:Jeff Darling
ID: 39961622
I know this was already solved, but I tried it in MS SQL 2005 without using cross apply and a table.

This may help someone else with a similar issue with XML Namespaces.

DECLARE @myxml as XML;
set @myxml='<InstantIDModelResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Header xmlns="http://webservices.seisint.com/WsIdentity">
    <Status>0</Status>
    <QueryId>1234</QueryId>
    <TransactionId>1311111R700000</TransactionId>
  </Header>
  <Result xmlns="http://webservices.seisint.com/WsIdentity">
    <InputEcho>
      <Name>
        <First>TOM</First>
        <Last>SMITH</Last>
      </Name>
      <Address>
        <StreetAddress1>123 Main St</StreetAddress1>
        <City>DESOTO</City>
        <State>TX</State>
        <Zip5>75110</Zip5>
      </Address>
      <DOB>
        <Year>1980</Year>
        <Month>1</Month>
        <Day>15</Day>
      </DOB>
      <Age>34</Age>
      <SSN>123456789</SSN>
      <HomePhone>4697219454</HomePhone>
    </InputEcho>
    <Models>
      <Model>
        <Name>ConsumerVerificationIndex</Name>
        <Scores>
          <Score>
            <Type>nas</Type>
            <Value>8</Value>
            <HighRiskIndicators>
              <HighRiskIndicator>
                <RiskCode>03</RiskCode>
                <Description>The input SSN was issued prior to the input date-of-birth</Description>
                <Sequence>1</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>26</RiskCode>
                <Description>Unable to verify SSN/TIN</Description>
                <Sequence>2</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>27</RiskCode>
                <Description>Unable to verify phone number</Description>
                <Sequence>3</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>52</RiskCode>
                <Description>The input first name is not associated with input SSN</Description>
                <Sequence>4</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>10</RiskCode>
                <Description>The input phone number is a mobile number</Description>
                <Sequence>5</Sequence>
              </HighRiskIndicator>
              <HighRiskIndicator>
                <RiskCode>82</RiskCode>
                <Description>The input name and address return a different phone number</Description>
                <Sequence>6</Sequence>
              </HighRiskIndicator>
            </HighRiskIndicators>
          </Score>
        </Scores>
      </Model>
    </Models>
    <DOBVerified>true</DOBVerified>
  </Result>
</InstantIDModelResponse>';


;WITH XMLNAMESPACES ('http://webservices.seisint.com/WsIdentity'  AS WS)

SELECT
  Nodes.node.value('WS:RiskCode[1]', 'varchar(10)')  RiskCode,
  Nodes.node.value('WS:Description[1]', 'varchar(100)')   [Description],
  Nodes.node.value('WS:Sequence[1]', 'varchar(100)') Sequence
FROM
@myxml.nodes('InstantIDModelResponse/WS:Result/WS:Models/WS:Model/WS:Scores/WS:Score/WS:HighRiskIndicators/WS:HighRiskIndicator') AS Nodes(node);	

Open in new window


MS SQL Query XML with namespaces Example
0
 
LVL 75

Expert Comment

by:Anthony Perkins
ID: 39963029
The reason you have to use CROSS APPLY is because you are going against an Xml column ("I'm trying to parse an XML field in a third party database") and more than likely the author will want to select values from the table.

Having said that, if this was a trivial case of querying an Xml variable then yes for sure you are on the right track.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

What if you have to shut down the entire Citrix infrastructure for hardware maintenance, software upgrades or "the unknown"? I developed this plan for "the unknown" and hope that it helps you as well. This article explains how to properly shut down …
Microsoft Access has a limit of 255 columns in a single table; SQL Server allows tables with over 255 columns, but reading that data is not necessarily simple.  The final solution for this task involved creating a custom text parser and then reading…
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.
Via a live example, show how to setup several different housekeeping processes for a SQL Server.

916 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