简体   繁体   中英

OPENXML to extract data from XML and add to the table

I have a XML file from where I want to get the data and place it into the SQL table. My problem is the path is different in the same XML file.

For an example,

one path = 'root/DescriptorRecord/DescriptorName'

second path = 'root/DescriptorRecord/ConceptList/Concept/TermList/Term'

I have no clue that how to get a value from two different path in a same XML.

Following is my XML :

<root>
<DescriptorRecord DescriptorClass = "1">
  <DescriptorName>
   <String>abc</String>
  </DescriptorName>
  <ConceptList>
   <Concept PreferredConceptYN="Y">
    <TermList>
     <Term  ConceptPreferredTermYN="Y"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="Y">
        <String>abc</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="N"  RecordPreferredTermYN="N">
        <String>pqr</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="N">
        <String>xyz</String>
    </Term>
   </TermList>
   </Concept>
  </ConceptList>
 </DescriptorRecord>
 <DescriptorRecord DescriptorClass = "1">
  <DescriptorName>
   <String>Numerics</String>
  </DescriptorName>
  <ConceptList>
   <Concept PreferredConceptYN="Y">
    <TermList>
     <Term  ConceptPreferredTermYN="Y"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="Y">
        <String>123</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="N"  RecordPreferredTermYN="N">
        <String>456</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="N">
        <String>789</String>
    </Term>
   </TermList>
   </Concept>
  </ConceptList>
 </DescriptorRecord>
 </root>

My SQL query :

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT Descriptor, Terms
FROM OPENXML(@hDoc, 'root/DescriptorRecord/DescriptorName')
WITH 
(
 Descriptor [varchar](100) 'String',
 Terms [varchar](100) 'String'
)

  SELECT Terms
  FROM OPENXML(@hDoc, 'root/DescriptorRecord/ConceptList/Concept/TermList/Term')
  WITH 
  (
    Descriptor [varchar](100) 'String'
    Terms [varchar](100) 'String'
  )

EXEC sp_xml_removedocument @hDoc
GO

Result :

http://imgur.com/wvS1pNL,JpApXuQ

Expected Result

http://imgur.com/wvS1pNL,JpApXuQ#1

So, setting up your sample in a variable:

DECLARE @X XML =  N'<root>
<DescriptorRecord DescriptorClass = "1">
  <DescriptorName>
   <String>abc</String>
  </DescriptorName>
  <ConceptList>
   <Concept PreferredConceptYN="Y">
    <TermList>
     <Term  ConceptPreferredTermYN="Y"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="Y">
        <String>abc</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="N"  RecordPreferredTermYN="N">
        <String>pqr</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="N">
        <String>xyz</String>
    </Term>
   </TermList>
   </Concept>
  </ConceptList>
 </DescriptorRecord>
 <DescriptorRecord DescriptorClass = "1">
  <DescriptorName>
   <String>Numerics</String>
  </DescriptorName>
  <ConceptList>
   <Concept PreferredConceptYN="Y">
    <TermList>
     <Term  ConceptPreferredTermYN="Y"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="Y">
        <String>123</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="N"  RecordPreferredTermYN="N">
        <String>456</String>
     </Term>
     <Term  ConceptPreferredTermYN="N"  IsPermutedTermYN="N"  LexicalTag="NON"  PrintFlagYN="Y"  RecordPreferredTermYN="N">
        <String>789</String>
    </Term>
   </TermList>
   </Concept>
  </ConceptList>
 </DescriptorRecord>
 </root>'

You'll want to select the descriptors first in an inner query, and return the results to an outer query, where you can use the descriptor column as a xpath criteria in the second .nodes() call. Like so:

SELECT Descriptor.Data.value('./DescriptorName[1]/String[1]','nvarchar(200)') AS Descriptor, Terms.Data.value('.','nvarchar(200)') AS Terms
FROM @x.nodes('root/DescriptorRecord') Descriptor(Data)
    cross apply Descriptor.Data.nodes('./ConceptList/Concept/TermList/Term/String') Terms(Data)

EDIT: An attempt to make it less computationally expensive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM