Udostępnij za pośrednictwem


Budowa XML (XQuery)

W XQuery, można użyć direct i computed konstruktory do konstruowania struktury XML kwerendy.

Ostrzeżenie

Możliwość obliczenia nazwy węzłów podczas korzystania z konstruktorów obliczanej nie jest obsługiwany przed SQL Server.Dlatego nie ma żadnej różnicy między direct i computed konstruktorów.

W przed SQL Server, obsługiwane są tylko tryb budowy, taśmy i zasady XMLSpace lub zasady owiatło granicę listwy.

Za pomocą bezpośredniego konstruktory

Użyć konstruktorów bezpośredniego, określeniu składni XML podobne podczas konstruowania XML.Poniższe przykłady ilustrują konstrukcji XML przez bezpośrednie konstruktorów.

Konstruowanie elementów

Korzystając z notacji XML, można utworzyć elementy.Poniższy przykład używa wyrażenie konstruktora elementu bezpośrednie i tworzy <ProductModel> elementu.Skonstruowane element ma trzy elementy podrzędność

  • Węzeł tekstowy.

  • Dwa węzły elementu, <Podsumowanie> i <Funkcje>.

    • <Podsumowanie> element ma jeden węzeł tekstu podrzędność których wartość jest "Niektóre opis".

    • <Funkcje> element ma trzy elementy podrzędne węzła elementu, <Kolor>, <wagi>, i <gwarancji>.Każdy z tych węzłów ma jeden element podrzędność węzeł tekstu i mają wartości czerwonego, 25, 2 lata części i robociznę, odpowiednio.

declare @x xml
set @x=''
select @x.query('<ProductModel ProductModelID="111">
This is product model catalog description.
<Summary>Some description</Summary>
<Features>
  <Color>Red</Color>
  <Weight>25</Weight>
  <Warranty>2 years parts and labor</Warranty>
</Features></ProductModel>')

Jest to wynikowe XML:

<ProductModel ProductModelID="111">
  This is product model catalog description.
  <Summary>Some description</Summary>
  <Features>
    <Color>Red</Color>
    <Weight>25</Weight>
    <Warranty>2 years parts and labor</Warranty>
  </Features>
</ProductModel>

Chociaż konstruowanie elementów z stała wyrażeń, jak w poniższym przykładzie jest przydatne, true zasilania tej funkcji języka XQuery jest zdolność do konstruowania XML, który dynamicznie wyodrębnia dane z bazy danych.Nawiasy klamrowe służy do określania wyrażenia kwerendy.Wynikowy XML wyrażenie zastępuje jego wartość.Na przykład następujące kwerendy konstrukcje <NewRoot> element o jeden element podrzędność elementu (<e>).Wartość elementu <e> obliczone ("{...}"), określając wyrażenie ścieżka wewnątrz nawiasy klamrowe.

DECLARE @x xml
SET @x='<root>5</root>'
SELECT @x.query('<NewRoot><e> { /root } </e></NewRoot>')

Nawiasy klamrowe jako tokeny przełączania kontekstu i przełącznik kwerendy XML budowy oceny kwerendy.W tym przypadek wyrażenie XQuery ścieżka wewnątrz nawiasów klamrowych, /root, szacowania i wyniki są zastępowane go

Jest to wynikiem:

<NewRoot>
  <e>
    <root>5</root>
  </e>
</NewRoot>

Następująca kwerenda jest podobny do poprzedniego.Jednak wyrażenie w nawiasy klamrowe określa data() funkcja, aby pobrać wartość niepodzielny <root> element i przypisuje go do konstruowanej elementu <e>.

DECLARE @x xml
SET @x='<root>5</root>'
DECLARE @y xml
SET @y = (SELECT @x.query('
                           <NewRoot>
                             <e> { data(/root) } </e>
                           </NewRoot>' ))
SELECT @y

Jest to wynikiem:

<NewRoot>
  <e>5</e>
</NewRoot>

Jeśli chcesz użyć jako część tekstu zamiast przełączania kontekstu tokeny nawiasy klamrowe, można je jako escape "}}" lub "{{", jak w poniższym przykładzie:

DECLARE @x xml
SET @x='<root>5</root>'
DECLARE @y xml
SET @y = (SELECT @x.query('
<NewRoot> Hello, I can use {{ and  }} as part of my text</NewRoot>'))
SELECT @y

Jest to wynikiem:

<NewRoot> Hello, I can use { and  } as part of my text</NewRoot>

Następująca kwerenda jest inny przykład konstruowanie elementów za pomocą konstruktora bezpośredniego elementu.Ponadto wartość <FirstLocation> element jest uzyskiwana przez wykonywanie wyrażenie w nawiasy klamrowe.Wyrażenie kwerendy zwraca czynności produkcyjnych w miejscu pierwszej pracy Centrum z instrukcjami kolumna w tabela Production.ProductModel.

SELECT Instructions.query('
    declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
        <FirstLocation>
           { /AWMI:root/AWMI:Location[1]/AWMI:step }
        </FirstLocation> 
') as Result 
FROM Production.ProductModel
WHERE ProductModelID=7

Jest to wynikiem:

<FirstLocation>
  <AWMI:step xmlns:AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions">
      Insert <AWMI:material>aluminum sheet MS-2341</AWMI:material> into the <AWMI:tool>T-85A framing tool</AWMI:tool>. 
  </AWMI:step>
  <AWMI:step xmlns:AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions">
      Attach <AWMI:tool>Trim Jig TJ-26</AWMI:tool> to the upper and lower right corners of the aluminum sheet. 
  </AWMI:step>
   ...
</FirstLocation>

Zawartości elementu XML budowy

Poniższy przykład ilustruje zachowanie wyrażeń w konstruowaniu zawartości elementu za pomocą konstruktora bezpośredniego elementu.W poniższym przykładzie konstruktora elementu bezpośrednie Określa jedno wyrażenie.Dla tego wyrażenie tworzony jest jeden węzeł tekstu w wynikowym pliku XML.

declare @x xml
set @x='
<root>
  <step>This is step 1</step>
  <step>This is step 2</step>
  <step>This is step 3</step>
</root>'
select @x.query('
<result>
 { for $i in /root[1]/step
    return string($i)
 }
</result>')

Wynikające z oceny wyrażenie sekwencji niepodzielny wartość jest dodawana do węzła tekstu ze spacją między sąsiadujących niepodzielny wartości, jak pokazano w wyniku.Skonstruowane element ma jeden element podrzędność.To jest węzeł tekstu, który zawiera wartość wykazaną w wyniku.

<result>This is step 1 This is step 2 This is step 3</result>

Zamiast jednego wyrażenie określić trzy oddzielne wyrażenie generowania trzy węzły tekstu, węzły sąsiadującego tekstu są scalane do węzła jednolity tekst przez łączenie w wynikowym pliku XML.

declare @x xml
set @x='
<root>
  <step>This is step 1</step>
  <step>This is step 2</step>
  <step>This is step 3</step>
</root>'
select @x.query('
<result>
 { string(/root[1]/step[1]) }
 { string(/root[1]/step[2]) }
 { string(/root[1]/step[3]) }
</result>')

Węzeł elementu konstruowanej ma jeden element podrzędność.To jest węzeł tekstu, który zawiera wartość wykazaną w wyniku.

<result>This is step 1This is step 2This is step 3</result>

Konstruowanie atrybutów

Gdy elementy są konstruowanie przy użyciu konstruktora elementu bezpośrednie, można również określić atrybuty elementu przy użyciu składni XML podobne jak w poniższym przykładzie:

declare @x xml
set @x=''
select @x.query('<ProductModel ProductModelID="111">
This is product model catalog description.
<Summary>Some description</Summary>
</ProductModel>')

Jest to wynikowe XML:

<ProductModel ProductModelID="111">
  This is product model catalog description.
  <Summary>Some description</Summary>
</ProductModel>

Skonstruowane element <ProductModel> ma atrybut ProductModelID i te węzły podrzędność:

  • Węzeł tekstowy This is product model catalog description.

  • Węzeł elementu, <Summary>.Ten węzeł ma jeden element podrzędność węzeł tekstu, Some description.

Podczas są konstruowania atrybut, można określić jej wartość na wyrażenie w nawiasy klamrowe.W tym przypadek wynikiem wyrażenie jest zwracany jako wartość atrybut.

W poniższym przykładzie data() funkcja nie jest bezwzględnie wymagany.Ponieważ wartość wyrażenie są przypisywane do atrybut data() niejawnie zastosowano pobrać wpisaną wartość określonego wyrażenie.

DECLARE @x xml
SET @x='<root>5</root>'
DECLARE @y xml
SET @y = (SELECT @x.query('<NewRoot attr="{ data(/root) }" ></NewRoot>'))
SELECT @y

Jest to wynikiem:

<NewRoot attr="5" />

Oto inny przykład określono wyrażenia dla budowy atrybut LocationID i SetupHrs.Wyrażenia te są sprawdzane XML kolumna instrukcji.Wpisane wartości wyrażenie jest przypisany do atrybutów.

SELECT Instructions.query('
    declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
        <FirstLocation 
         LocationID="{ (/AWMI:root/AWMI:Location[1]/@LocationID)[1] }"
         SetupHrs = "{ (/AWMI:root/AWMI:Location[1]/@SetupHours)[1] }" >
           { /AWMI:root/AWMI:Location[1]/AWMI:step }
        </FirstLocation> 
') as Result 
FROM  Production.ProductModel
where ProductModelID=7

Jest to wynik częściowy:

<FirstLocation LocationID="10" SetupHours="0.5" >
  <AWMI:step … 
  </AWMI:step>
  ...
</FirstLocation>

Ograniczenia wdrażania

Są następujące ograniczenia:

  • Wiele lub mieszane (ciąg i wyrażenie XQuery) atrybut wyrażenia nie są obsługiwane.Na przykład, jak pokazano w następującej kwerendzie, można utworzyć XML gdzie Item jest stała i wartość 5 uzyskuje się poprzez ocenę wyrażenie kwerendy:

    <a attr="Item 5" />
    

    Następująca kwerenda zwraca błąd, ponieważ są mieszanie stała ciąg na wyrażenie ({/ x}) i to nie jest obsługiwany:

    DECLARE @x xml
    SET @x ='<x>5</x>'
    SELECT @x.query( '<a attr="Item {/x}"/>' ) 
    

    W takim przypadek są następujące opcje:

    • Formularz wartość atrybut przez łączenie dwóch wartości niepodzielny.Wartości te niepodzielny są szeregowane w wartości atrybut spacji między wartościami niepodzielny:

      SELECT @x.query( '<a attr="{''Item'', data(/x)}"/>' ) 
      

      Jest to wynikiem:

      <a attr="Item 5" />
      
    • Użyj Funkcja ZŁĄCZ Aby złączyć ciąg dwa argumenty do wynikowej wartości atrybut:

      SELECT @x.query( '<a attr="{concat(''Item'', /x[1])}"/>' ) 
      

      W tym przypadek nie ma spacji między tymi dwoma ciąg wartości.Jeśli ma miejsce między dwiema wartościami musi jawnie podaj go.

      Jest to wynikiem:

      <a attr="Item5" />
      
  • Wiele wyrażeń jako wartość atrybut nie są obsługiwane.Na przykład poniższa kwerenda zwraca błąd:

    DECLARE @x xml
    SET @x ='<x>5</x>'
    SELECT @x.query( '<a attr="{/x}{/x}"/>' )
    
  • Heterogenicznych sekwencji nie są obsługiwane.Próby przypisywać heterogenicznych sekwencji wartość atrybut zwróci błąd, jak pokazano w następującym przykładzie.W tym przykładzie sekwencji heterogenicznych, ciąg "Pozycja" i element <x>, jest określany jako wartość atrybut:

    DECLARE @x xml
    SET @x ='<x>5</x>'
    select @x.query( '<a attr="{''Item'', /x }" />')
    

    Jeśli zastosujesz data() funkcja, działa kwerendy, ponieważ pobiera niepodzielny wartość wyrażenie, /x, który jest łączone z ciąg.Sekwencja wartości niepodzielny jest następujący:

    SELECT @x.query( '<a attr="{''Item'', data(/x)}"/>' ) 
    

    Jest to wynikiem:

    <a attr="Item 5" />
    
  • Kolejność węzłów atrybutu są wymuszane podczas serializacji, a nie podczas kontrola typów statycznego.Na przykład poniższa kwerenda zawiedzie, ponieważ próbuje dodać atrybut po węzłem bez atrybutów.

    select convert(xml, '').query('
    element x { attribute att { "pass" }, element y { "Element text" }, attribute att2 { "fail" } }
    ')
    go
    

    Powyższa kwerenda zwraca następujący komunikat o błędzie:

    XML well-formedness check: Attribute cannot appear outside of element declaration. Rewrite your XQuery so it returns well-formed XML.
    

Dodawanie nazw

Przy konstruowaniu XML przy użyciu bezpośredniego konstruktory, zbudowane element i atrybut nazwy mogą zostać zakwalifikowane za pomocą prefiks obszaru nazw.Prefiks obszaru nazw można powiązać w następujący sposób:

  • Za pomocą atrybut deklaracja obszaru nazw.

  • Za pomocą klauzula Z XMLNAMESPACES.

  • W prologu XQuery.

Dodawanie nazw przy użyciu atrybut deklaracji obszaru nazw

W poniższym przykładzie użyto atrybut deklaracja obszaru nazw w budowie element <a> zadeklarować domyślny obszar nazw.Budowa element podrzędność <b> cofa deklaracja domyślny obszar nazw zadeklarowane w elemencie nadrzędnym.

declare @x xml
set @x ='<x>5</x>'
select @x.query( '
  <a xmlns="a">
    <b />
  </a>' ) 

Jest to wynikiem:

<a xmlns="a">
  <b  />
</a>

Można przypisać prefiks obszaru nazw.Prefiks jest określona w budowie element <a>.

declare @x xml
set @x ='<x>5</x>'
select @x.query( '
  <x:a xmlns:x="a">
    <b/>
  </x:a>' )

Jest to wynikiem:

<x:a xmlns:x="a">
  <b />
</x:a>

Począwszy od SQL Server 2005, można un-zadeklarować domyślny obszar nazw w konstrukcji XML, ale nie un-zadeklarować prefiks obszaru nazw.Następująca kwerenda zwraca błąd, ponieważ nie un-zadeklarować prefiks, jak określono w budowie element <b>.

declare @x xml
set @x ='<x>5</x>'
select @x.query( '
  <x:a xmlns:x="a">
    <b xmlns:x=""/>
  </x:a>' )

Nowo zbudowanych obszar nazw jest dostępne do użycia wewnątrz kwerendy.Na przykład, poniższa kwerenda deklaruje nazw w konstruowaniu elementu, <FirstLocation>i określa prefiks w wyrażeniach LocationID i SetupHrs atrybut wartości.

SELECT Instructions.query('
        <FirstLocation xmlns:AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
         LocationID="{ (/AWMI:root/AWMI:Location[1]/@LocationID)[1] }"
         SetupHrs = "{ (/AWMI:root/AWMI:Location[1]/@SetupHours)[1] }" >
           { /AWMI:root/AWMI:Location[1]/AWMI:step }
        </FirstLocation> 
') as Result 
FROM  Production.ProductModel
where ProductModelID=7

Należy zauważyć, że tworzenie nowy prefiks obszaru nazw w ten sposób zastępują wszelkie istniejące deklaracja obszaru nazw dla tego prefiksu.Na przykład deklaracja obszaru nazw AWMI="http://someURI", w kwerendzie prolog jest zastępowany deklaracja obszaru nazw w <FirstLocation> elementu.

SELECT Instructions.query('
declare namespace AWMI="http://someURI";
        <FirstLocation xmlns:AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"
         LocationID="{ (/AWMI:root/AWMI:Location[1]/@LocationID)[1] }"
         SetupHrs = "{ (/AWMI:root/AWMI:Location[1]/@SetupHours)[1] }" >
           { /AWMI:root/AWMI:Location[1]/AWMI:step }
        </FirstLocation> 
') as Result 
FROM  Production.ProductModel
where ProductModelID=7

Dodawanie nazw przy użyciu prologu

Ten przykład ilustruje, jak obszary nazw mogą być dodane do konstruowanej XML.Domyślny obszar nazw jest zadeklarowany w prologu kwerendy.

declare @x xml
set @x ='<x>5</x>'
select @x.query( '
           declare default element namespace "a";
            <a><b /></a>' )

Należy zauważyć, że w budowie element <b>, atrybut deklaracja obszaru nazw jest określany za pomocą pustego ciąg jako wartość.To un-deklaruje domyślny obszar nazw jest zadeklarowany w obiekcie nadrzędnym.

This is the result:
<a xmlns="a">
  <b  />
</a>

Budowa XML i białe miejsca obsługi

Zawartość elementu konstrukcji XML może zawierać znaków spacji.Znaki te są obsługiwane w następujący sposób:

  • Znaki spacji w obszarze nazw URI są traktowane jako typ XSD anyURI.W szczególności jest sposób obsługi:

    • Wszystkie znaki spacji na początku i na końcu zostaną obcięte.

    • Wartości znaków spacji wewnętrznego są zwijane w jednym miejscu

  • Znaki wysuwu wiersza wewnątrz zawartości atrybut zastępuje spacje.Są one inne znaki spacji jest zachowywana.

  • Białe miejsca wewnątrz elementów jest zachowywany.

Poniższy przykład ilustruje białe miejsca obsługi konstrukcji XML:

-- line feed is repaced by space.
declare @x xml
set @x=''
select @x.query('

declare namespace myNS="   http://     
 abc/
xyz

";
<test attr="    my 
test   attr 
value    " >

<a>

This     is  a

test

</a>
</test>
') as XML_Result 

 

Jest to wynikiem:

-- result
<test attr="<test attr="    my test   attr  value    "><a>

This     is  a

test

</a></test>
"><a>

This     is  a

test

</a></test>

Inne bezpośrednie konstruktory XML

Konstruktory przetwarzania instrukcje i komentarze XML używa takiej samej składni, odpowiedniej konstrukcji XML.Obliczone konstruktorów dla węzłów tekstu są również obsługiwane, ale są głównie używane w XML DML do konstruowania węzłów tekstowych.

Uwagaprzykład za pomocą konstruktora węzła jawnego tekstu Zobacz przykład określonych w Wstaw (XML DML).

W następującej kwerendzie skonstruowany kod XML zawiera element, dwa atrybuty, komentarz i instrukcję przetwarzania.Należy zauważyć, że przecinek jest używany przed <FirstLocation>, ponieważ sekwencja jest generowana.

SELECT Instructions.query('
  declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
   <?myProcessingInstr abc="value" ?>, 
   <FirstLocation 
        WorkCtrID = "{ (/AWMI:root/AWMI:Location[1]/@LocationID)[1] }"
        SetupHrs = "{ (/AWMI:root/AWMI:Location[1]/@SetupHours)[1] }" >
       <!-- some comment -->
       <?myPI some processing instructions ?>
       { (/AWMI:root/AWMI:Location[1]/AWMI:step) }
    </FirstLocation> 
') as Result 
FROM Production.ProductModel
where ProductModelID=7

Jest to wynik częściowy:

<?myProcessingInstr abc="value" ?>
<FirstLocation WorkCtrID="10" SetupHrs="0.5">
  <!-- some comment -->
  <?myPI some processing instructions ?>
  <AWMI:step xmlns:AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions">I
  nsert <AWMI:material>aluminum sheet MS-2341</AWMI:material> into the <AWMI:tool>T-85A framing tool</AWMI:tool>. 
  </AWMI:step>
    ...
/FirstLocation>

Za pomocą obliczanej konstruktory

.In this case, you specify the keywords that identify the type of node you want to construct.Obsługiwane są tylko następujące słowa kluczowe:

  • element

  • atrybut

  • tekst

Węzły elementów i atrybut tych słów kluczowych następuje nazwa węzła i przez wyrażenie ujęte w nawiasy klamrowe, który generuje również zawartość dla tego węzła.W poniższym przykładzie są konstruowanie XML to:

<root>
  <ProductModel PID="5">Some text <summary>Some Summary</summary></ProductModel>
</root>

To jest kwerenda, że używa obliczone konstruktory Generuj XML:

declare @x xml
set @x=''
select @x.query('element root 
               { 
                  element ProductModel
     {
attribute PID { 5 },
text{"Some text "},
    element summary { "Some Summary" }
 }
               } ')

Wyrażenie, które generuje węzła zawartości można określić w wyrażeniu kwerendy.

declare @x xml
set @x='<a attr="5"><b>some summary</b></a>'
select @x.query('element root 
               { 
                  element ProductModel
     {
attribute PID { /a/@attr },
text{"Some text "},
    element summary { /a/b }
 }
               } ')

Należy zauważyć, że obliczony element i atrybut konstruktory, jak zdefiniowano w specyfikacji XQuery umożliwiają obliczanie nazwy węzła.Kiedy używasz konstruktory bezpośrednie w SQL Server, nazwy węzłów, takich jak elementów i atrybut, musi być określona jako stała literałów.Dlatego jest różnicy w bezpośredniej konstruktorów i obliczanych konstruktorów elementów i atrybutów.

W poniższym przykładzie zawartości dla węzłów zbudowane są uzyskiwane z instrukcje wytwarzania XML, które są przechowywane kolumna instrukcje xml Typ danych w tabela ProductModel.

SELECT Instructions.query('
  declare namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
   element FirstLocation 
     {
        attribute LocationID { (/AWMI:root/AWMI:Location[1]/@LocationID)[1] },
        element   AllTheSteps { /AWMI:root/AWMI:Location[1]/AWMI:step }
     }
') as Result 
FROM  Production.ProductModel
where ProductModelID=7

Jest to wynik częściowy:

<FirstLocation LocationID="10">
  <AllTheSteps>
    <AWMI:step> ... </AWMI:step>
    <AWMI:step> ... </AWMI:step>
    ...
  </AllTheSteps>
</FirstLocation>  

Dodatkowe ograniczenia implementacji

Obliczona atrybut konstruktorów nie można deklarować nowych nazw.Ponadto następujące obliczone konstruktory nie są obsługiwane w SQL Server:

  • Konstruktory węzła obliczanej dokumentu

  • Konstruktory instrukcji przetwarzania obliczanych

  • Konstruktory obliczanej komentarz

Zobacz także

Koncepcje