Delen via


Naamruimten toevoegen aan query's met BEHULP van XMLNAMESPACES

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

MET XMLNAMESPACES (Transact-SQL) biedt ondersteuning voor naamruimte-URI's op de volgende manier:

Gebruik WITH XMLNAMESPACES in FOR XML-queries

Met XMLNAMESPACES kunt u XML-naamruimten opnemen in FOR XML-query's. Denk bijvoorbeeld aan de volgende FOR XML-query:

SELECT ProductID, Name, Color
FROM   Production.Product
WHERE  ProductID IN (316, 317)
FOR XML RAW;

Dit is het resultaat:

<row ProductID="316" Name="Blade" />
<row ProductID="317" Name="LL Crankarm" Color="Black" />

Als u naamruimten wilt toevoegen aan de XML die is samengesteld door de FOR XML-query, geeft u eerst het voorvoegsel voor de naamruimte op voor URI-toewijzingen met behulp van de component WITH NAMESPACES. Gebruik vervolgens de voorvoegsels van de naamruimte bij het opgeven van de namen in de query, zoals wordt weergegeven in de volgende gewijzigde query. De component WITH XMLNAMESPACES geeft het naamruimtevoorvoegsel (ns1) aan URI -toewijzing (uri) op. Het voorvoegsel ns1 wordt vervolgens gebruikt bij het opgeven van het element en de kenmerknamen die moeten worden samengesteld door de FOR XML-query.

WITH XMLNAMESPACES ('uri' as ns1)
SELECT ProductID as 'ns1:ProductID',
       Name      as 'ns1:Name',
       Color     as 'ns1:Color'
FROM  Production.Product
WHERE ProductID IN (316, 317)
FOR XML RAW ('ns1:Prod'), ELEMENTS;

Het XML-resultaat bevat de voorvoegsels van de naamruimte:

<ns1:Prod xmlns:ns1="uri">
  <ns1:ProductID>316</ns1:ProductID>
  <ns1:Name>Blade</ns1:Name>
</ns1:Prod>
<ns1:Prod xmlns:ns1="uri">
  <ns1:ProductID>317</ns1:ProductID>
  <ns1:Name>LL Crankarm</ns1:Name>
  <ns1:Color>Black</ns1:Color>
</ns1:Prod>

Het volgende is van toepassing op de WITH XMLNAMESPACES-clausule:

  • Het wordt alleen ondersteund in de modi RAW, AUTO en PATH van de FOR XML-query's. De EXPLICIETe modus wordt niet ondersteund.

  • Dit is alleen van invloed op de naamruimtevoorvoegsels van FOR XML-query's en de xml- gegevenstypemethoden, maar niet op de XML-parser. De volgende query retourneert bijvoorbeeld een fout, omdat het XML-document geen naamruimtedeclaratie heeft voor het myNS-voorvoegsel.

  • De FOR XML-instructies, XMLSCHEMA en XMLDATA kunnen niet worden gebruikt wanneer een WITH XMLNAMESPACES-component wordt gebruikt.

    CREATE TABLE T (x xml);
    GO
    WITH XMLNAMESPACES ('https://abc' as myNS )
    INSERT INTO T VALUES('<myNS:root/>');
    GO
    

De XSINIL-instructie gebruiken

U kunt het xsi-voorvoegsel niet definiƫren in de clausule WITH XMLNAMESPACES, als u de XSINIL-instructie ELEMENTS gebruikt. In plaats daarvan wordt deze automatisch toegevoegd wanneer u ELEMENTS XSINIL gebruikt. De volgende query maakt gebruik van ELEMENTS XSINIL waarmee elementgerichte XML wordt gegenereerd, waarbij null-waarden worden toegewezen aan elementen met het kenmerk xsi:nil ingesteld op True.

WITH XMLNAMESPACES ('uri' as ns1)
SELECT ProductID as 'ns1:ProductID',
       Name      as 'ns1:Name',
       Color     as 'ns1:Color'
FROM Production.Product
WHERE ProductID = 316
FOR XML RAW, ELEMENTS XSINIL;

Dit is het resultaat:

<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="uri">
  <ns1:ProductID>316</ns1:ProductID>
  <ns1:Name>Blade</ns1:Name>
  <ns1:Color xsi:nil="true" />
</row>

Standaardnaamruimten opgeven

In plaats van een naamruimtevoorvoegsel te declareren, kunt u een standaardnaamruimte declareren met behulp van een STANDAARDwoord. In de FOR XML-query wordt de standaardnaamruimte gekoppeld aan XML-knooppunten in de resulterende XML. In het volgende voorbeeld definieert DE WITH XMLNAMESPACES twee naamruimtevoorvoegsels die samen met een standaardnaamruimte worden gedefinieerd.

WITH XMLNAMESPACES ('uri1' as ns1,
                    'uri2' as ns2,
                    DEFAULT 'uri2')
SELECT ProductID,
      Name,
      Color
FROM Production.Product
WHERE ProductID IN (316, 317)
FOR XML RAW ('ns1:Product'), ROOT('ns2:root'), ELEMENTS;

De FOR XML-query genereert elementgerichte XML. De query gebruikt beide naamruimtevoorvoegsels in naamgevingsknooppunten. In de SELECT-component geeft de ProductID, Naam en Kleur geen naam op met een voorvoegsel. Daarom behoren de bijbehorende elementen in de resulterende XML tot de standaardnaamruimte.

<ns2:root xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">
  <ns1:Product>
    <ProductID>316</ProductID>
    <Name>Blade</Name>
  </ns1:Product>
  <ns1:Product>
    <ProductID>317</ProductID>
    <Name>LL Crankarm</Name>
    <Color>Black</Color>
  </ns1:Product>
</ns2:root>

De volgende query is vergelijkbaar met de vorige, behalve dat de MODUS VOOR XML AUTO is opgegeven.

WITH XMLNAMESPACES ('uri1' as ns1,  'uri2' as ns2,DEFAULT 'uri2')
SELECT ProductID,
      Name,
      Color
FROM Production.Product as "ns1:Product"
WHERE ProductID IN (316, 317)
FOR XML AUTO, ROOT('ns2:root'), ELEMENTS;

Vooraf gedefinieerde naamruimten gebruiken

Wanneer u vooraf gedefinieerde naamruimten gebruikt, behalve de XML-naamruimte en de xsi-naamruimte wanneer ELEMENTS XSINIL wordt gebruikt, moet u expliciet de naamruimtebinding opgeven met BEHULP van XMLNAMESPACES. Met de volgende query wordt het naamruimtevoorvoegsel expliciet gedefinieerd voor de URI-binding voor de voorgedefinieerde naamruimte (urn:schemas-microsoft-com:xml-sql).

WITH XMLNAMESPACES ('urn:schemas-microsoft-com:xml-sql' as sql)
SELECT 'SELECT * FROM Customers FOR XML AUTO, ROOT("a")' AS "sql:query"
FOR XML PATH('sql:root');

Dit is het resultaat. SQLXML-gebruikers zijn bekend met deze XML-sjabloon. Zie SQLXML 4.0 Programming Conceptsvoor meer informatie.

<sql:root xmlns:sql="urn:schemas-microsoft-com:xml-sql">
  <sql:query>SELECT * FROM Customers FOR XML AUTO, ROOT("a")</sql:query>
</sql:root>

Alleen het voorvoegsel van de XML-naamruimte kan worden gebruikt zonder dit expliciet te definiƫren in WITH XMLNAMESPACES, zoals wordt weergegeven in de volgende PATH-modusquery. Als het voorvoegsel wordt gedeclareerd, moet het ook worden gebonden aan de naamruimte http://www.w3.org/XML/1998/namespace. De namen die zijn opgegeven in de SELECT-component verwijzen naar het voorvoegsel van de XML-naamruimte dat niet expliciet is gedefinieerd met BEHULP van XMLNAMESPACES.

SELECT 'en'    as "English/@xml:lang",
       'food'  as "English",
       'ger'   as "German/@xml:lang",
       'Essen' as "German"
FOR XML PATH ('Translation');
GO

De @xml:lang kenmerken maken gebruik van de vooraf gedefinieerde XML-naamruimte. Omdat xml-versie 1.0 niet de expliciete declaratie van de XML-naamruimtebinding vereist, bevat het resultaat geen expliciete declaratie van de naamruimtebinding.

Dit is het resultaat:

<Translation>
  <English xml:lang="en">food</English>
  <German xml:lang="ger">Essen</German>
</Translation>

GEBRUIKEN MET XMLNAMESPACES met de methoden voor xml-gegevenstypen

De XML-gegevenstypemethoden opgegeven in een SELECT-query of in UPDATE wanneer dit de modify() methode is, moeten alle de naamruimtedeclaratie in hun prolog herhalen. Dit kan tijdrovend zijn. Met de volgende query worden bijvoorbeeld productmodel-id's opgehaald waarvan de catalogusbeschrijvingen specificatie bevatten. Dat wil gezegd, het <Specifications> element bestaat.

SELECT ProductModelID, CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
    <Product
        ProductModelID= "{ sql:column("ProductModelID") }"
        />
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
    declare namespace  pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
     /pd:ProductDescription[(pd:Specifications)]'
    ) = 1;

In de vorige query declareren zowel de query()- als de exist()-methode dezelfde namespace in de proloog. Bijvoorbeeld:

declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";

U kunt ook eerst MET XMLNAMESPACES declareren en de voorvoegsels van de naamruimte in de query gebruiken. In dit geval hoeven de methoden query() en exist() geen naamruimtedeclaraties in hun prolog op te nemen.

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' as pd)
SELECT ProductModelID, CatalogDescription.query('
    <Product
        ProductModelID= "{ sql:column("ProductModelID") }"
        />
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
     /pd:ProductDescription[(pd:Specifications)]'
    ) = 1;
GO

Een expliciete declaratie in de XQuery proloog overschrijft het namespace-prefix en de standaard-elementnamespace die zijn gedefinieerd in de WITH-clause.

Zie ook