Udostępnij za pośrednictwem


Budowa XML (XQuery)

W XQuery, można użyć direct i computed Konstruktorzy do konstruowania struktury XML w ciągu kwerendy.

Uwaga

Zdolność do obliczenia nazwy węzłów, korzystając z obliczoną konstruktorów nie jest obsługiwany przed SQL Server. Dlatego też 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 XMLSpace zasad lub zasady odstępu granicę, taśmy.

Za pomocą bezpośredniego konstruktory

Korzystając z konstruktorów bezpośrednie, określ składni XML podobne podczas konstruowania XML.Poniższe przykłady ilustrują konstrukcji XML przez bezpośrednie konstruktorów.

Tworząc elementy

Korzystając z notacji XML, można utworzyć elementów.W poniższym przykładzie za pomocą wyrażenie konstruktora elementu bezpośrednie i tworzy <ProductModel> element. Skonstruowana element ma trzy elementy podrzędność

  • Węzeł tekstu.

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

    • The <Summary> element has one text node podrzędność whose value is "Some description".

    • The <Features> element has three element node children, <Color>, <Weight>, and <Warranty>.Każdy z tych węzłów ma jeden element podrzędność węzeł tekst i wartości Red, 25, 2 lat części i robociznę, są 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 wynikowy plik 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>

Konstruowanie elementów z wyrażeń stałych, jak w poniższym przykładzie jest przydatne, true zasilania z tej funkcji języka XQuery jest zdolność do konstruowania XML, które dynamicznie wyodrębnia dane z bazy danych.Nawiasy klamrowe służy do określania wyrażenia kwerendy.W wynikowym pliku 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>jest obliczana przez określenie wyrażenie ścieżka w 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 z konstrukcji XML do oceny kwerendy.W tym przypadek wyrażenie ścieżka XQuery wewnątrz nawiasów klamrowych, /root, sprawdzana jest zgodność i wyniki są zastępowane go.

To jest wynik:

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

Następująca kwerenda jest podobna do poprzedniego.Jednak wyrażenie w nawiasy klamrowe określa data() funkcja, aby pobrać wartość niepodzielny <root> element i przypisuje go do elementu zbudowane <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

To jest wynik:

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

Jeśli chcesz użyć jako część tekstu zamiast do przełączania kontekstu tokeny nawiasy klamrowe, można je jako escape "}}"lub"{{", jak pokazano 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

To jest wynik:

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

Następująca kwerenda jest innym przykładem tworzenia elementów za pomocą konstruktora bezpośredniego elementu.Ponadto wartości <FirstLocation> element jest uzyskiwany przez wyrażenie w nawiasy klamrowe. Wyrażenie kwerendy zwraca kroki produkcji w miejscu pierwszego gniazda pracy z kolumna w tabela Production.ProductModel instrukcji.

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

To jest wynik:

<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ść elementu w przygotowaniu XML

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

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>')

Sekwencja niepodzielny wartość powstałe w wyniku oceny wyrażenie jest dodawany do węzła tekstu ze spacją między sąsiadujących ze sobą wartości niepodzielny, jak pokazano w wyniku.Element zbudowane ma jeden element podrzędność.To jest węzeł tekst, który zawiera wartość widoczna w wyniku.

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

Zamiast jednego wyrażenie określenia trzech oddzielnych wyrażenie generowania trzech węzłów tekstu, węzły sąsiadującego tekstu są scalane w jeden tekst węzła, 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 zbudowane ma jeden element podrzędność.To jest węzeł tekst, który zawiera wartość widoczna w wyniku.

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

Konstruowanie atrybuty

Podczas elementy są tworzenia za pomocą konstruktora bezpośredniego elementu, 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 wynikowy plik XML:

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

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

  • Węzłem tekstu This is product model catalog description.

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

Przy są konstruowaniu 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 absolutnie konieczne. Ponieważ wartość wyrażenie jest przypisywana do atrybut, data() Domyślnie jest stosowane do pobrania 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

To jest wynik:

<NewRoot attr="5" />

Poniżej znajduje się inny przykład określono wyrażeń LocationID i SetupHrs przygotowaniu atrybut.Wyrażenia te są sprawdzane przed 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>

defaultButton

Ograniczenia są następujące:

  • Wiele lub mieszane (ciąg znaków 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 w przypadku gdy Item jest stała i wartości 5 uzyskuje się poprzez ocenę kwerendy wyrażenie:

    <a attr="Item 5" />
    

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

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

    W takim przypadek użytkownik ma następujące opcje:

    • Wartość atrybut formularza przez łączenie z dwóch wartości niepodzielny.Te wartości niepodzielny są szeregowane do wartości atrybut spacji między niepodzielny wartości:

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

      To jest wynik:

      <a attr="Item 5" />
      
    • Użycie Funkcja concat Aby złączyć ciąg dwóch argumentów w wynikowej wartości atrybut:

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

      W takim przypadek nie ma miejsca między nimi ciąg wartości.Jeśli chcesz, aby obszar między dwiema wartościami, musi jawnie podaj go.

      To jest wynik:

      <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}"/>' )
    
  • Heterogeniczne sekwencji nie są obsługiwane.Dowolne próby przypisania heterogenicznych sekwencji, zgodnie z wartością atrybut zwróci błąd, jak pokazano w poniższym przykładzie.W tym przykładzie, heterogenicznych sekwencji, ciąg "Element" i elementu <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 kwerendy skuteczny, ponieważ pobiera niepodzielny wartość wyrażenie, /x, który jest połączenie z ciągiem. Sekwencja niepodzielny wartości jest następujący:

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

    To jest wynik:

    <a attr="Item 5" />
    
  • Atrybut kolejności węzłów są wymuszane podczas serializacji, a nie podczas kontrola typów statycznego.Na przykład poniższa kwerenda nie działa, 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 obszarów nazw

Przy konstruowaniu XML przy użyciu bezpośredniego konstruktorów, zbudowane element i atrybut nazwy może kwalifikowane przy użyciu prefiksu obszaru nazw.Można powiązać prefiks obszaru nazw w następujący sposób:

  • Korzystając z atrybut deklaracja obszaru nazw.

  • Za pomocą klauzula WITH XMLNAMESPACES.

  • W prologu XQuery.

Dodawanie obszarów nazw przy użyciu programu do obszaru nazw deklaracja atrybut

W poniższym przykładzie użyto do budowy element do obszaru nazw deklaracja atrybut <a> Aby 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>' ) 

To jest wynik:

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

Prefiks można przypisać do obszaru nazw.Prefiks jest określona w budowie elementu <a>.

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

To jest wynik:

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

Zaczyna się od SQL Server 2005, można odinstalować - zadeklarować domyślny obszar nazw w budowie XML, ale nie można odinstalować - zadeklarować prefiks obszaru nazw. Następująca kwerenda zwraca błąd, ponieważ nie można odinstalować - zadeklarować prefiksu określonemu w budowie elementu <b>.

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

Nowo zbudowane obszaru nazw jest dostępna do używania wewnątrz kwerendy.Na przykład poniższa kwerenda deklaruje obszaru nazw przy konstruowaniu elementu, <FirstLocation>, a Określa prefiks w wyrażeniach wartości atrybut LocationID i SetupHrs.

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 nowego prefiksu obszaru nazw w ten sposób spowoduje zastąpienie wszystkich istniejących deklaracja obszaru nazw dla tego prefiksu.Na przykład deklaracja obszaru nazw AWMI="http://someURI", w kwerendzie prologu zostanie zastąpione przez deklarację obszaru nazw w <FirstLocation> element.

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

Aby dodać obszary nazw przy użyciu prologu

Ten przykład ilustruje, jak obszary nazw mogą być dodawane do skonstruowany kod XML.Domyślny obszar nazw został 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 elementu <b>, atrybut deklaracja obszaru nazw jest określany za pomocą pusty ciąg znaków jako jego wartość. To un-deklaruje domyślny obszar nazw, które są zadeklarowane w obiekcie nadrzędnym.

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

Znak odstępu obsługi i przygotowaniu XML

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

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

    • Wszystkie znaki odstępu — na początku i końca są obcięte.

    • Wartości znaków odstępu wewnętrzne są zwijane w jednym miejscu

  • Znaki wysuwu wiersza wewnątrz zawartość atrybut są zastępowane spacjami.Wszystkie inne znaki odstępu — nadal są one.

  • Odstęp 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 

 

To jest wynik:

-- 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

Konstruktorzy do przetwarzania instrukcji i komentarze XML należy użyć takiej samej składni, jak odpowiadające im konstrukcji XML.Obliczona konstruktorów tekstu węzły są również obsługiwane, ale są stosowane głównie w XML DML w celu skonstruowania węzłów tekstowych.

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

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

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ą konstruktory obliczanych

.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

Dla węzłów elementów i atrybut te słowa kluczowe są następuje nazwa węzła i wyrażenie ujęte w nawiasy klamrowe, które 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życie obliczona konstruktorów wygenerować plik 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 zawartość węzła 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 element obliczane i konstruktorzy atrybut, jak zdefiniowano w specyfikacji XQuery pozwala na obliczenia nazwy węzłów.Kiedy korzystasz z bezpośredniego konstruktorów w SQL Server, nazwy węzłów, takie jak elementów i atrybut, musi być określona jako stała literałów. Dlatego nie ma żadnej różnicy w bezpośrednim konstruktorów i obliczanej 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 instrukcji 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 dotyczące implementacji

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

  • Konstruktorzy węzła obliczanej dokumentu

  • Konstruktorzy instrukcji przetwarzania obliczanych

  • Konstruktorzy obliczanej komentarza

See Also

Concepts