Aracılığıyla paylaş


XML yapısı (XQuery)

Şunlar için geçerlidir: SQL Server

XQuery'de, sorgu içinde XML yapıları oluşturmak için doğrudan ve hesaplanan oluşturucuları kullanabilirsiniz.

Uyarı

Doğrudan ve hesaplanan oluşturucular arasında bir fark yoktur.

Doğrudan oluşturucuları kullanma

Doğrudan oluşturucuları kullandığınızda, XML'yi oluştururken XML benzeri söz dizimi belirtirsiniz. Aşağıdaki örneklerde doğrudan oluşturucuların XML yapısı gösterilmektedir.

Öğe oluşturma

XML gösterimini kullanarak öğeleri oluşturabilirsiniz. Aşağıdaki örnek doğrudan öğe oluşturucu ifadesini kullanır ve bir <ProductModel> öğe oluşturur. Yapılan öğe üç alt öğeye sahiptir

  • Metin düğümü.

  • İki öğe düğümü <Summary> ve <Features>.

    • öğesinin <Summary> değeri olan "Some description"bir metin düğümü alt öğesi vardır.

    • öğesinin <Features> üç öğe düğümü alt öğesi vardır: <Color>, <Weight>ve <Warranty>. Bu düğümlerin her birinin bir metin düğümü alt öğesi vardır ve sırasıyla , 25, 2 years parts and labordeğerlerine Redsahiptir.

DECLARE @x AS 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>');

Sonuçta elde edilen XML aşağıdadır:

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

Bu örnekte gösterildiği gibi sabit ifadelerden öğe oluşturmak yararlı olsa da, bu XQuery dili özelliğinin gerçek gücü, veritabanından verileri dinamik olarak ayıklayan XML oluşturma özelliğidir. Sorgu ifadelerini belirtmek için küme ayraçlarını kullanabilirsiniz. Sonuçta elde edilen XML'de ifade değeriyle değiştirilir. Örneğin, aşağıdaki sorgu bir alt öğe (<e>) ile bir <NewRoot> öğe oluşturur. öğesinin <e> değeri, küme ayraçları içinde bir yol ifadesi belirtilerek hesaplanır ("{ ... }").

DECLARE @x AS XML;

SET @x = '<root>5</root>';

SELECT @x.query('<NewRoot><e> { /root } </e></NewRoot>');

Küme ayraçları bağlam değiştirme belirteçleri gibi davranır ve sorguyu XML yapısından sorgu değerlendirmesine geçirir. Bu durumda, ayraçların /rootiçindeki XQuery yol ifadesi değerlendirilir ve sonuçlar bunun yerine kullanılır.

Sonuç şu şekildedir:

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

Aşağıdaki sorgu, öncekine benzer. Bununla birlikte, küme ayraçlarındaki ifade öğenin atomik değerini <root> almak için işlevini belirtir data() ve bunu , yapısına <e>atar.

DECLARE @x AS XML;
SET @x = '<root>5</root>';

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

SELECT @y;

Sonuç şu şekildedir:

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

Bağlam değiştirme belirteçleri yerine metninizin bir parçası olarak küme ayraçlarını kullanmak istiyorsanız, bu örnekte gösterildiği gibi bu küme ayraçlarından "}}" veya "{{" olarak kaçabilirsiniz:

DECLARE @x AS XML;
SET @x = '<root>5</root>';

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

SELECT @y;

Sonuç şu şekildedir:

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

Aşağıdaki sorgu, doğrudan öğe oluşturucusunu kullanarak öğe oluşturmanın başka bir örneğidir. Ayrıca, öğesinin <FirstLocation> değeri, küme ayraçlarında ifade yürütülerek elde edilir. Sorgu ifadesi, Production.ProductModel tablosunun Instructions sütunundaki ilk iş merkezi konumundaki üretim adımlarını döndürür.

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;

Sonuç şu şekildedir:

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

XML yapısındaki öğe içeriği

Aşağıdaki örnekte, doğrudan öğe oluşturucu kullanılarak öğe içeriği oluşturmada ifadelerin davranışı gösterilmektedir. Aşağıdaki örnekte, doğrudan öğe oluşturucu bir ifade belirtir. Bu ifade için, sonuçta elde edilen XML'de bir metin düğümü oluşturulur.

DECLARE @x AS 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>');

İfade değerlendirmesinden kaynaklanan atomik değer dizisi, metin düğümüne, sonuçta gösterildiği gibi bitişik atomik değerler arasına boşluk eklenmiş olarak eklenir. Yapılan öğenin bir alt öğesi vardır. Bu, sonuçta gösterilen değeri içeren bir metin düğümüdür.

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

Bir ifade yerine, üç metin düğümü oluşturan üç ayrı ifade belirtirseniz, bitişik metin düğümleri, sonuçta elde edilen XML'de birleştirme yoluyla tek bir metin düğümünde birleştirilir.

DECLARE @x AS 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>');

Yapılan öğe düğümünde bir alt öğe vardır. Bu, sonuçta gösterilen değeri içeren bir metin düğümüdür.

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

Öznitelikleri oluşturma

Doğrudan öğe oluşturucu kullanarak öğeleri oluştururken, bu örnekte gösterildiği gibi XML benzeri söz dizimini kullanarak öğenin özniteliklerini de belirtebilirsiniz:

DECLARE @x AS XML;
SET @x = '';

SELECT @x.query('<ProductModel ProductModelID="111">;
This is product model catalog description.
<Summary>Some description</Summary>
</ProductModel>');

Sonuçta elde edilen XML aşağıdadır:

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

Oluşturulan öğe <ProductModel> bir ProductModelID özniteliğine ve şu alt düğümlere sahiptir:

  • Bir metin düğümü, This is product model catalog description.

  • Bir öğe düğümü, <Summary>. Bu düğümün bir metin düğümü alt öğesi vardır: Some description.

Bir öznitelik oluştururken, değerini küme ayraçlarındaki bir ifadeyle belirtebilirsiniz. Bu durumda, ifadenin sonucu öznitelik değeri olarak döndürülür.

Aşağıdaki örnekte işlev data() kesinlikle gerekli değildir. İfade değerini bir özniteliğe atadığınızdan, data() belirtilen ifadenin türü belirtilmiş değerini almak için örtük olarak uygulanır.

DECLARE @x AS XML;
SET @x = '<root>5</root>';

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

SELECT @y;

Sonuç şu şekildedir:

<NewRoot attr="5" />

Aşağıda, LocationID ve SetupHrs öznitelik yapısı için ifadelerin belirtildiği başka bir örnek verilmiştir. Bu ifadeler, Yönerge sütunundaki XML'ye göre değerlendirilir. İfadenin yazılan değeri özniteliklere atanır.

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;

Kısmi sonuç aşağıdadır:

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

Uygulama sınırlamaları

Sınırlamalar şunlardır:

  • Birden çok veya karışık (dize ve XQuery ifadesi) öznitelik ifadeleri desteklenmez. Örneğin, aşağıdaki sorguda gösterildiği gibi, bir sorgu ifadesi değerlendirilerek sabit ve değer 5 elde edilen XML Item oluşturursunuz:

    <a attr="Item 5" />
    

    Sabit dizeyi bir ifadeyle ({/x}) karıştırdığınızdan ve bu desteklenmediğinden aşağıdaki sorgu bir hata döndürür:

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

    Bu durumda, aşağıdaki seçeneklere sahip olursunuz:

    • İki atomik değerin birleşerek öznitelik değerini oluşturur. Bu atomik değerler, atomik değerler arasında bir boşlukla öznitelik değeri olarak serileştirilir:

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

      Sonuç şu şekildedir:

      <a attr="Item 5" />
      
    • İki dize bağımsız değişkenini sonuçta elde edilen öznitelik değeriyle birleştirmek için concat işlevini kullanın:

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

      Bu durumda, iki dize değeri arasına boşluk eklenmez. İki değer arasında boşluk istiyorsanız, bunu açıkça sağlamanız gerekir.

      Sonuç şu şekildedir:

      <a attr="Item5" />
      
  • Öznitelik değeri olarak birden çok ifade desteklenmez. Örneğin, aşağıdaki sorgu bir hata döndürür:

    DECLARE @x AS XML;
    SET @x = '<x>5</x>';
    
    SELECT @x.query('<a attr="{/x}{/x}"/>');
    
  • Heterojen diziler desteklenmez. Heterojen bir diziyi öznitelik değeri olarak atama girişimi, aşağıdaki örnekte gösterildiği gibi bir hata döndürür. Bu örnekte heterojen bir dizi, "Item" dizesi ve öğesi <x>öznitelik değeri olarak belirtilir:

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

    İşlevi data() uygularsanız, sorgu dizeyle birleştirilmiş ifadenin /xatomik değerini aldığından çalışır. Atomik değerlerin dizisi aşağıdadır:

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

    Sonuç şu şekildedir:

    <a attr="Item 5" />
    
  • Öznitelik düğümü sırası, statik tür denetimi yerine serileştirme sırasında zorlanır. Örneğin, öznitelik olmayan bir düğümden sonra öznitelik eklemeye çalıştığından aşağıdaki sorgu başarısız olur.

    SELECT CONVERT (XML, '').query('
        element x { attribute att { "pass" }, element y { "Element text" }, attribute att2 { "fail" } }
        ');
    GO
    

    Önceki sorgu aşağıdaki hatayı döndürür:

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

Ad alanları ekleme

Doğrudan oluşturucuları kullanarak XML oluştururken, yapılandırılmış öğe ve öznitelik adları bir ad alanı ön eki kullanılarak nitelenebilir. Ön eki ad alanına aşağıdaki yollarla bağlayabilirsiniz:

  • Ad alanı bildirim özniteliğini kullanarak.
  • yan tümcesini WITH XMLNAMESPACES kullanarak.
  • XQuery giriş günlüğünde.

Ad alanları eklemek için ad alanı bildirim özniteliği kullanma

Aşağıdaki örnek, varsayılan ad alanını bildirmek için öğesinin <a> yapısında bir ad alanı bildirim özniteliği kullanır. Alt öğenin oluşturulması, üst öğede <b> bildirilen varsayılan ad alanının bildirimini geri alır.

DECLARE @x AS XML;
SET @x = '<x>5</x>';

SELECT @x.query('
  <a xmlns="a">
    <b xmlns=""/>
  </a>');

Sonuç şu şekildedir:

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

Ad alanına bir ön ek atayabilirsiniz. ön eki öğesinin <a>yapısında belirtilir.

DECLARE @x AS XML;
SET @x = '<x>5</x>';

SELECT @x.query('
  <x:a xmlns:x="a">
    <b/>
  </x:a>');

Sonuç şu şekildedir:

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

XML yapısında varsayılan ad alanını un-declare yapabilirsiniz, ancak ad alanı ön eki bildirimini kaldıramazsınız. Öğesinin <b>yapısında belirtilen ön eki bildiremediğiniz için aşağıdaki sorgu bir hata döndürür.

DECLARE @x AS XML;
SET @x = '<x>5</x>';

SELECT @x.query('
  <x:a xmlns:x="a">
    <b xmlns:x=""/>
  </x:a>');

Yeni yapılan ad alanı sorgunun içinde kullanılabilir. Örneğin, aşağıdaki sorgu öğesini <FirstLocation>oluştururken bir ad alanı bildirir ve LocationID ve SetupHrs öznitelik değerlerinin ifadelerindeki ön eki belirtir.

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;

Bu şekilde yeni bir ad alanı ön eki oluşturmak, bu ön ek için önceden var olan ad alanı bildirimlerini geçersiz kılar. Örneğin, sorgu günlüğündeki ad alanı bildirimi öğesindeki AWMI="https://someURI"ad alanı bildirimi <FirstLocation> tarafından geçersiz kılınabilir.

SELECT Instructions.query('
declare namespace AWMI="https://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;

Ad alanları eklemek için bir prolog kullanma

Bu örnekte, ad alanlarının, oluşturulacak XML'e nasıl eklenebilecekleri gösterilmektedir. Sorgu girişinde varsayılan ad alanı bildirilir.

DECLARE @x AS XML;
SET @x = '<x>5</x>';

SELECT @x.query('
           declare default element namespace "a";
            <a><b xmlns=""/></a>');

öğesinin <b>oluşturulmasında, ad alanı bildirim özniteliği değeri boş bir dizeyle belirtilir. Bu, üst öğede bildirilen varsayılan ad alanını un-declares.

Sonuç şu şekildedir:

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

XML yapısı ve boşluk işleme

XML yapısındaki öğe içeriği boşluk karakterleri içerebilir. Bu karakterler aşağıdaki yollarla işlenir:

  • Ad alanı URI'lerindeki boşluk karakterleri XSD türü anyURIolarak değerlendirilir. Özellikle, bunlar şu şekilde işlenir:

    • Başlangıç ve bitişte boşluk karakterleri kırpılır.
    • İç boşluk karakter değerleri tek bir boşlukta daraltılır
  • Öznitelik içeriğinin içindeki satır besleme karakterleri boşluklarla değiştirilir. Diğer tüm boşluk karakterleri olduğu gibi kalır.

  • Öğelerin içindeki boşluk korunur.

Aşağıdaki örnekte XML yapısında boşluk işleme gösterilmektedir:

-- line feed is replaced by space.
DECLARE @x AS XML;
SET @x = '';

SELECT @x.query('

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

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

<a>

This     is  a

test

</a>
</test>
') AS XML_Result;

Sonuç şu şekildedir:

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

This     is  a

test

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

This     is  a

test

</a></test>

Diğer doğrudan XML oluşturucuları

Yönergeleri ve XML açıklamalarını işlemek için oluşturucular, karşılık gelen XML yapısı söz dizimi ile aynı söz dizimini kullanır. Metin düğümleri için hesaplanan oluşturucular da desteklenir, ancak öncelikle içinde metin düğümleri oluşturmak için kullanılır XML DML .

Uyarı

Açık bir metin düğümü oluşturucu kullanma örneği için , insert (XML DML) içindeki belirli örne bakın.

Aşağıdaki sorguda, oluşturan XML bir öğe, iki öznitelik, bir açıklama ve bir işleme yönergesi içerir. Bir dizi oluşturulurken virgülden <FirstLocation>önce kullanılır.

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;

Kısmi sonuç aşağıdadır:

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

Hesaplanan oluşturucuları kullanma

Bu durumda, oluşturmak istediğiniz düğüm türünü tanımlayan anahtar sözcükleri belirtirsiniz. Yalnızca aşağıdaki anahtar sözcükler desteklenir:

  • öğesi
  • Öznitelik
  • Başka bir metin sağlanmadığı için, verilen metne dayalı bir çeviri yapmam mümkün değil. Lütfen çevirilecek metni belirtin.

Öğe ve öznitelik düğümleri için bu anahtar sözcüklerin ardından düğüm adı ve bu düğümün içeriğini oluşturan küme ayraçları içine alınmış ifade gelir. Aşağıdaki örnekte, bu XML'yi oluşturursunuz:

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

Hesaplanan oluşturucuların XML'yi oluşturmasını sağlayan sorgu aşağıdadır:

DECLARE @x AS XML;
SET @x = '';

SELECT @x.query('element root
               {
                  element ProductModel
     {
attribute PID { 5 },
text{"Some text "},
    element summary { "Some Summary" }
 }
               } ');

Düğüm içeriğini oluşturan ifade bir sorgu ifadesi belirtebilir.

DECLARE @x AS 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 }
 }
               } ');

XQuery belirtiminde tanımlandığı gibi hesaplanan öğe ve öznitelik oluşturucuları düğüm adlarını hesaplamanıza olanak sağlar. SQL Server'da doğrudan oluşturucular kullanırken, öğe ve öznitelik gibi düğüm adları sabit değişmez değerler olarak belirtilmelidir. Bu nedenle, öğeler ve öznitelikler için doğrudan oluşturucular ve hesaplanan oluşturucular arasında bir fark yoktur.

Aşağıdaki örnekte, yapılandırılan düğümlerin içeriği ProductModel tablosundaki xml veri türünün Yönergeler sütununda depolanan XML üretim yönergelerinden alınmaktadır.

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;

Kısmi sonuç aşağıdadır:

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

Diğer uygulama sınırlamaları

Hesaplanan öznitelik oluşturucuları yeni bir ad alanı bildirmek için kullanılamaz. Ayrıca aşağıdaki hesaplanan oluşturucular SQL Server'da desteklenmez:

  • Hesaplanan belge düğümü oluşturucuları
  • Hesaplanan işleme yönerge oluşturucuları
  • Hesaplanan açıklama oluşturucuları