Dela via


Sökvägsuttryck – Specifikation av nodtest

gäller för:SQL Server

Ett axelsteg i ett sökvägsuttryck innehåller följande komponenter:

Mer information finns i Path Expressions (XQuery).

Ett nodtest är ett villkor och är den andra komponenten i axelsteget i ett sökvägsuttryck. Alla noder som valts i ett steg måste uppfylla det här villkoret. För sökvägsuttrycket /child::ProductDescriptionär nodtestet ProductDescription. Det här steget hämtar endast de elementnodsbarn vars namn är ProductDescription.

Ett nodtestvillkor kan innehålla följande:

  • Ett nodnamn. Endast noder av huvudnodtypen med det angivna namnet returneras.

  • En nodtyp. Endast noder av den angivna typen returneras.

Not

Nodnamn som anges i XQuery-sökvägsuttryck omfattas inte av samma kollationskänsliga regler som Transact-SQL-frågor och är alltid skiftlägeskänsliga.

Nodnamn som nodtest

När du anger ett nodnamn som ett nodtest i ett steg för sökvägsuttryck måste du förstå begreppet typ av huvudnod. Varje axel, underordnad, överordnad eller attribut, har en huvudtyp av nod. Till exempel:

  • En attributaxel kan bara innehålla attribut. Därför är attributnoden huvudnodens typ av attributaxel.

  • För andra axlar, om noder valda av axeln kan innehålla elementnoder, är elementet huvudnodtyp för den axeln.

När du anger ett nodnamn som ett nodtest returnerar steget följande typer av noder:

  • Noder av huvudnodtyp för axeln.

  • Noder som har samma namn som anges i nodtestet.

Tänk till exempel på följande sökvägsuttryck:

child::ProductDescription   

Det här ettstegsuttrycket anger en child axel och nodnamnet ProductDescription som nodtest. Uttrycket returnerar endast de noder som är av huvudnodens typ av underaxel, elementnoder och som har ProductDescription som namn.

Sökvägsuttrycket /child::PD:ProductDescription/child::PD:Features/descendant::*, har tre steg. De här stegen anger barn- och avkomlingsaxlar. I varje steg anges nodnamnet som nodtest. Jokertecknet (*) i det tredje steget anger alla noder av principnodtypen för den underordnade axeln. Huvudnodens typ av axel avgör vilken typ av noder som valts och nodnamnet filtrerar de valda noderna.

När detta uttryck körs mot XML-dokumenten i produktkatalogen i tabellen ProductModel, hämtar det alla elementnodsbarn till elementnoden <Features>, som i sin tur är ett elementnodsbarn till elementet <ProductDescription>.

Sökvägsuttrycket /child::PD:ProductDescription/attribute::ProductModelIDbestår av två steg. Båda dessa steg anger ett nodnamn som nodtest. Dessutom använder det andra steget attributaxeln. Därför väljer varje steg noder av huvudslaget på dess axel som har det namn som anges i nodtestet. Uttrycket returnerar därför ProductModelID- attributnod för <ProductDescription>-elementnoden.

När du anger namnen på noder för nodtester kan du också använda jokertecknet (*) för att ange det lokala namnet på en nod eller för dess namnområdesprefix, som du ser i följande exempel:

declare @x xml  
set @x = '  
<greeting xmlns="ns1">  
   <salutation>hello</salutation>  
</greeting>  
<greeting xmlns="ns2">  
   <salutation>welcome</salutation>  
</greeting>  
<farewell xmlns="ns1" />'  
select @x.query('//*:greeting')  
select @x.query('declare namespace ns="ns1"; /ns:*')  

Nodtyp som nodtest

Om du vill fråga efter andra nodtyper än elementnoder använder du ett nodtyptest. Som du ser i följande tabell finns det fyra nodtypstester tillgängliga.

Nodtyp Returnerar Exempel
comment() Sant för en kommentarsnod. following::comment() markerar alla kommentarsnoder som visas efter kontextnoden.
node() Sant för en nod av något slag. preceding::node() markerar alla noder som visas före kontextnoden.
processing-instruction() Sant för en bearbetningsinstruktionsnod. self::processing instruction() väljer alla bearbetningsinstruktionsnoder i kontextnoden.
text() Sant för en textnod. child::text() väljer de textnoder som är underordnade kontextnoden.

Om nodtypen, till exempel text() eller comment() ... anges som nodtestet, returnerar steget bara noder av den angivna typen, oavsett huvudnodtypen för axeln. Följande sökvägsuttryck returnerar till exempel endast kommentarnodens underordnade till kontextnoden:

child::comment()  

På samma sätt hämtar /child::ProductDescription/child::Features/child::comment() kommentarsnodens underordnade <-funktioner> elementnod underordnad <ProductDescription>-elementnoden.

Exempel

I följande exempel jämförs nodnamn och nodtyp.

A. Resultat av att ange nodnamnet och nodtypen som nodtester i ett sökvägsuttryck

I följande exempel tilldelas ett enkelt XML-dokument till en xml- typvariabel. Dokumentet efterfrågas med hjälp av olika sökvägsuttryck. Resultatet jämförs sedan.

declare @x xml  
set @x='  
<a>  
 <b>text1  
   <c>text2  
     <d>text3</d>  
   </c>  
 </b>  
</a>'  
select @x.query('  
/child::a/child::b/descendant::*  
')  

Det här uttrycket frågar efter noderna för underordnade element i <b>-elementnoden.

Asterisken (*) i nodtestet anger ett jokertecken för nodnamnet. Den underordnade axeln har elementnoden som sin primära nodtyp. Därför returnerar uttrycket alla underordnade elementnoder i elementnoden <b>. Det innebär att elementnoder <c> och <d> returneras, vilket visas i följande resultat:

<c>text2  
     <d>text3</d>  
</c>  
<d>text3</d>  

Om du anger en underordnad eller egen axel i stället för att ange en underordnad axel returneras kontextnoden och även dess underordnade:

/child::a/child::b/descendant-or-self::*  

Det här uttrycket returnerar elementnoden <b> och dess underordnade elementnoder. När de underordnade noderna returneras avgör den primära nodens typ av underordnad-eller-själv-axel, elementnodtyp, vilken typ av noder som returneras.

Det här är resultatet:

<b>text1  
   <c>text2  
     <d>text3</d>  
   </c>  
</b>  
  
<c>text2  
     <d>text3</d>  
</c>  
  
<d>text3</d>   

Det föregående uttrycket använde ett jokertecken som nodnamn. I stället kan du använda funktionen node(), som du ser i det här uttrycket:

/child::a/child::b/descendant::node()  

Eftersom node() är en nodtyp får du alla noder på den underordnade axeln. Det här är resultatet:

text1  
<c>text2  
     <d>text3</d>  
</c>  
text2  
<d>text3</d>  
text3  

Om du anger underordnad-eller-själv-axel och node() som nodtest får du alla underordnade, element och textnoder, och även kontextnoden, <b>-elementet.

<b>text1  
   <c>text2  
     <d>text3</d>  
   </c>  
</b>  
text1  
<c>text2  
     <d>text3</d>  
</c>  
text2  
<d>text3</d>  
text3  

B. Ange ett nodnamn i nodtestet

I följande exempel anges ett nodnamn som nodtest i alla sökvägsuttryck. Därför returnerar alla uttryck noder för huvudnodens typ av axel som har nodnamnet angivet i nodtestet.

Följande frågeuttryck returnerar det <Warranty> elementet från produktkatalogens XML-dokument som lagras i tabellen Production.ProductModel:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::wm:Warranty  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Observera följande från föregående fråga:

  • Nyckelordet namespace i XQuery-prolog definierar ett prefix som används i frågetexten. Mer information om XQuery-prolog finns i XQuery Prolog .

  • Alla tre stegen i sökvägsuttrycket anger den underordnade axeln och ett nodnamn som nodtest.

  • Den valfria stegkvalificeringsdelen i axelsteget anges inte i något av stegen i uttrycket.

Frågan returnerar <Warranty>-elementens barn som är barn till <Features>-elementet som är barn till <ProductDescription>-elementet.

Det här är resultatet:

<wm:Warranty xmlns:wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain">  
  <wm:WarrantyPeriod>3 years</wm:WarrantyPeriod>  
  <wm:Description>parts and labor</wm:Description>  
</wm:Warranty>     

I följande fråga anger sökvägsuttrycket ett jokertecken (*) i ett nodtest.

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::*  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Jokertecknet anges för nodnamnet. Den här frågan returnerar därför alla elementnodsbarn för <Features>, som är ett barn till <ProductDescription>-elementnoden.

Följande fråga liknar den tidigare frågan, förutom att ett namnområde har angetts tillsammans med jokertecknet. Som ett resultat returneras alla elementnodsbarn i det namnområdet. Observera att elementet <Features> kan innehålla element från olika namnområden.

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::wm:*  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Du kan använda jokertecknet som ett namnområdesprefix, som du ser i den här frågan:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::*:Maintenance  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Den här sökningen returnerar barnen till <Maintenance>-elementnoden i alla namnrymder från produktkatalogens XML-dokument.

C. Ange nodtyp i nodtestet

I följande exempel anges nodtyp som nodtest i alla sökvägsuttryck. Därför returnerar alla uttryck noder av den typ som anges i nodtestet.

I följande fråga anger sökvägsuttrycket en nodtyp i det tredje steget:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::PD:Features/child::text()  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

I nästa fråga anges följande:

  • Sökvägsuttrycket har tre steg avgränsade med ett snedstreck (/).

  • Var och en av dessa steg anger en barnaxel.

  • De första två stegen anger ett nodnamn som nodtestet, och det tredje steget anger en nodtyp som nodtest.

  • Uttrycket returnerar textnodsbarn till <Features>-elementet som är barn till <ProductDescription>-elementnoden.

Endast en textnod returneras. Det här är resultatet:

These are the product highlights.   

Följande fråga returnerar de underordnade kommentarsnoderna till elementet <ProductDescription>.

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::PD:ProductDescription/child::comment()  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Observera följande från föregående fråga:

  • Det andra steget anger en nodtyp som nodtest.

  • Som ett resultat returnerar uttrycket kommentarnodernas barn inom <ProductDescription> elementnoderna.

Det här är resultatet:

<!-- add one or more of these elements... one for each specific product in this product model -->  
<!-- add any tags in <specifications> -->      

Följande fråga hämtar toppnivåns bearbetningsinstruktionsnoder:

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::processing-instruction()  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Det här är resultatet:

<?xml-stylesheet href="ProductDescription.xsl" type="text/xsl"?>   

Du kan skicka en literal strängparameter till nodtestet processing-instruction(). I det här fallet returnerar frågan de bearbetningsinstruktioner vars namnattributvärde är strängliteralen som anges i argumentet.

SELECT CatalogDescription.query('  
declare namespace PD="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  
declare namespace wm="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelWarrAndMain";  
 /child::processing-instruction("xml-stylesheet")  
')  
FROM Production.ProductModel  
WHERE ProductModelID=19  

Implementeringsbegränsningar

Följande är de specifika begränsningarna

  • De utökade SequenceType-nodtesterna stöds inte.

  • processing-instruction(name) stöds inte. Placera i stället namnet inom citattecken.