otrdiena, 2011. gada 6. septembris

Datu izgūšana no XML: XML vārdtelpas (namespaces)

Raksts ar piemēriem par to, kā SQL Server var izgūt datus no XML, kurā ir norādītas vārdtelpas.
Par XML vārdtelpām- w3schools, un msdn raksti: WITH XMLNAMESPACE un xquery.

[ja nekas nemainīsies, emuārā parādīsies daudz vairāk raksti par XML. Domāju- arī plašāk par vārdtelpām, pašu XML, xpath, xml datu tipu, utt .. šobrīd šis sanāk mazliet izrauts no konteksta]

Datu izgūšana bez vārdtelplas
Declare @myXML XML;
Set @myXML  =
N'
<PersonInfo>
    <Person ID="22">
        <Name>Jānis2</Name>
        <Profession>Galdnieks</Profession>
    </Person>
</PersonInfo>
';
SELECT
    @myXML.value('(PersonInfo/Person/@ID)[1]', 'nvarchar(100)') as ID,
    @myXML.value('(PersonInfo/Person/Name)[1]', 'nvarchar(100)') as Name,
    @myXML.value('(PersonInfo/Person/Profession)[1]', 'nvarchar(100)') as Profession;
Noklusētā vārdtelpa
Ja vaicājumā netiek norādīta noklusētā vārdtelpa, rezultāti netiek atgriezti. Šādi nestrādās:
Declare @myXML XML;
Set @myXML  =
N'
<PersonInfo xmlns="http://www.sqlblog.lv/default">
    <Person ID="22">
        <Name>Jānis2</Name>
        <Profession>Galdnieks</Profession>
    </Person>
</PersonInfo>
';
-- Šis nestrādā!
SELECT
    @myXML.value('(PersonInfo/Person/@ID)[1]', 'nvarchar(100)') as ID,
    @myXML.value('(PersonInfo/Person/Name)[1]', 'nvarchar(100)') as Name,
    @myXML.value('(PersonInfo/Person/Profession)[1]', 'nvarchar(100)') as Profession;
Norādīt var izmantojot WITH XMLNAMESPACES. šādi būs pareizi:
Declare @myXML XML;
Set @myXML  =
N'
<PersonInfo xmlns="http://www.sqlblog.lv/default">
    <Person ID="22">
        <Name>Jānis2</Name>
        <Profession>Galdnieks</Profession>
    </Person>
</PersonInfo>
';   
-- Šis strādā, jo ir XMLNamspace norādīts!
WITH XMLNAMESPACES (DEFAULT 'http://www.sqlblog.lv/default')
SELECT
    @myXML.value('(PersonInfo/Person/@ID)[1]', 'nvarchar(100)') as ID,
    @myXML.value('(PersonInfo/Person/Name)[1]', 'nvarchar(100)') as Name,
    @myXML.value('(PersonInfo/Person/Profession)[1]', 'nvarchar(100)') as Profession;
Norādīt var arī savādāk (pie Profession nekas norādīts, tādēļ tur tiek atgriezta NULL vērtība):
Declare @myXML XML;
Set @myXML  =
N'
<PersonInfo xmlns="http://www.sqlblog.lv/default">
    <Person ID="22">
        <Name>Jānis2</Name>
        <Profession>Galdnieks</Profession>
    </Person>
</PersonInfo>
';   
--Cits veids, kā norādīt (Profession netiek attēlots, jo nav zināms vai no pareizā namespace)
SELECT
    @myXML.value('declare default element namespace "http://www.sqlblog.lv/default";
        (PersonInfo/Person/@ID)[1]', 'nvarchar(100)') as ID,
    @myXML.value('declare default element namespace "http://www.sqlblog.lv/default";
        (PersonInfo/Person/Name)[1]', 'nvarchar(100)') as Name,
    @myXML.value('(PersonInfo/Person/Profession)[1]', 'nvarchar(100)') as Profession;
Darbs ar vairāk kā vienu vārdtelpu.
Izmantojot With XMLNAMESPACES:
Declare @myXML XML
Set @myXML  =
N'
<PersonInfo xmlns:my="http://www.sqlblog.lv/personName" xmlns="http://www.sqlblog.lv/default">
    <my:Person ID="21">
        <Name>Jānis1</Name>
        <LastName>Bērziņš</LastName>
    </my:Person>
    <Person ID="22">
        <Name>Jānis2</Name>
        <Profession>Galdnieks</Profession>
    </Person>
</PersonInfo>
';
WITH XMLNAMESPACES (
    'http://www.sqlblog.lv/personName' as my,
    DEFAULT 'http://www.sqlblog.lv/default'
    )
SELECT
    @myXML.value('(PersonInfo/my:Person/@ID)[1]', 'nvarchar(100)') as ID1,
    @myXML.value('(PersonInfo/Person/@ID)[1]', 'nvarchar(100)') as ID2,
    @myXML.value('(PersonInfo/my:Person/Name)[1]', 'nvarchar(100)') as Name1,
    @myXML.value('(PersonInfo/Person/Name)[1]', 'nvarchar(100)') as Name2,
    @myXML.value('(PersonInfo/my:Person/LastName)[1]', 'nvarchar(100)') as LastName,
    @myXML.value('(PersonInfo/Person/Profession)[1]', 'nvarchar(100)') as Profession
Otrs veids:
Declare @myXML XML;
Set @myXML  =
N'
<PersonInfo xmlns:my="http://www.sqlblog.lv/personName" xmlns="http://www.sqlblog.lv/default">
    <my:Person ID="21">
        <Name>Jānis1</Name>
        <LastName>Bērziņš</LastName>
    </my:Person>
    <Person ID="22">
        <Name>Jānis2</Name>
        <Profession>Galdnieks</Profession>
    </Person>
</PersonInfo>
';
SELECT
    @myXML.value('
        declare default element namespace "http://www.sqlblog.lv/default";
        declare namespace my="http://www.sqlblog.lv/personName";
        (PersonInfo/my:Person/@ID)[1]', 'nvarchar(100)') as ID

Nav komentāru:

Ierakstīt komentāru