10

Given table T with columns:

ID UNIQUEIDENTIFIER
CreatedDate DATETIME
XmlData XML

Where XmlData is structured like:

<application>
    <details firstname="first" lastname="last">
        <statement>statement</statement>
    </details>
    <educationHistory>
        <education subject="subject1" />
        <education subject="subject2" />
    </educationHistory>
    <experienceHistory>
        <examiningExperienceHistory>
            <examiningExperience module="module1" />
            <examiningExperience module="module2" />
        </examiningExperienceHistory>
        <teachingExperienceHistory>
            <teachingExperience module="module1" />
            <teachingExperience module="module2" />
        </teachingExperienceHistory>
    </experienceHistory>
</application>

I need to return an extract like so:

ID Date       FirstName LastName Education    ExaminingExp TeachingExp
-----------------------------------------------------------------------
1  02-10-2012 First     Last     <xmlextract> <xmlextract> <xmlextract>

So far I have:

SELECT ID,
       CreatedDate [Date],
       XmlData.value('(application/details/@firstname)[1]','varchar(max)') [FirstName],
       XmlData.value('(application/details/@lastname)[1]','varchar(max)') [LastName]
FROM T

I'm struggling with thee last three columns. For each record, I need to list teaching/examining experience, and education. Can anybody help?

Paul Fleming
  • 24,238
  • 8
  • 76
  • 113

2 Answers2

10

Use .query to extract xml.

eg

select 
XmlData.query('/application/educationHistory/*'),
XmlData.query('/application/experienceHistory/examiningExperienceHistory/*'),
XmlData.query('/application/experienceHistory/teachingExperienceHistory/*')
podiluska
  • 50,950
  • 7
  • 98
  • 104
  • This is great, thanks. Just to be cheeky, is there a way I can restrict what is returned in the query? e.g. instead of return the full xml under the path, return only certain attributes. So given ``, return only ``, – Paul Fleming Oct 02 '12 at 13:10
  • You can do `xmldata.query ('data(/application/educationHistory/education/@subject)')` which will get the value of the subject attribute – podiluska Oct 02 '12 at 13:15
  • @podiluska Not with query(), but with value(). – Jaime Oct 02 '12 at 13:18
  • 1
    You can filter the nodes you want to be returned. I.e. `@xmlVar.query('/application/educationHistory/education[@subject="subject1"]')`, but you cannot filter the returned attributes. Every attribute in the returned nodes will be returned – Jaime Oct 02 '12 at 13:18
  • @podiluska True, sorry, I misunderstood your comment. This returns the values of that attributes in all the nodes under that XQuery path. – Jaime Oct 02 '12 at 13:30
5

Try this:

SELECT ID, Created [DATE] 
XmlData.value('(application/details/@firstname)[1]','varchar(max)') [FirstName],
XmlData.value('(application/details/@lastname)[1]','varchar(max)') [LastName],
XmlData.query('/application/educationHistory'),
XmlData.query('/application/experienceHistory/examiningExperienceHistory'),
XmlData.query('/application/experienceHistory/teachingExperienceHistory')
FROM T
Jaime
  • 1,110
  • 1
  • 8
  • 14