Delen via


XPath Gegevenstypen (SQLXML 4.0)

Van toepassing op:SQL ServerAzure SQL Database

Microsoft SQL Server, XPath en XML Schema (XSD) hebben heel verschillende datatypes. XPath heeft bijvoorbeeld geen gehele of datumdatatypes, maar SQL Server en XSD hebben er wel veel. XSD gebruikt nanosecondenprecisie voor tijdswaarden, en SQL Server gebruikt maximaal 1/300 seconde precisie. Daarom is het niet altijd mogelijk om het ene datatype aan een ander toe te wijzen. Voor meer informatie over het koppelen van SQL Server-datatypes aan XSD-datatypes, zie Data Type Coercions en de sql:datatype Annotation (SQLXML 4.0).

XPath heeft drie datatypen: string, number en booleaan. Het getaldatatype is altijd een IEEE 754 dubbelprecisie floating-point. Het SQL Serverfloat(53) datatype ligt het dichtst bij het XPath-getal. Float(53) is echter niet precies IEEE 754. Bijvoorbeeld, noch NaN (Not-a-Number) noch oneindig wordt gebruikt. Proberen een niet-numerieke string om te zetten naar een getal en proberen te delen door nul resulteert in een fout.

XPath-conversies

Wanneer je een XPath-query OrderDetail[@UnitPrice > "10.0"]zoals gebruikt, kunnen impliciete en expliciete datatypeconversies de betekenis van de query op subtiele manieren veranderen. Daarom is het belangrijk om te begrijpen hoe XPath-datatypes worden geïmplementeerd. De XPath-taalspecificatie, XML Path Language (XPath) versie 1.0 W3C Voorgestelde Aanbeveling 8 oktober 1999, is te vinden op de W3C-website op http://www.w3.org/TR/1999/PR-xpath-19991008.html.

XPath-operators zijn onderverdeeld in vier categorieën:

  • Booleaanse operatoren (en, of)

  • Relationele operatoren (<, >, <, =, >=)

  • Gelijkheidsoperatoren (=, !=)

  • Rekenkundige operatoren (+, -, *, div, mod)

Elke categorie operatoren zet zijn operanden anders om. XPath-operatoren converteren impliciet hun operanden indien nodig. Rekenkundige operatoren zetten hun operanden om in getal, en resulteren in een getalwaarde. Booleaanse operatoren zetten hun operanden om naar Booleaanse en resulteren in een Booleaanse waarde. Relationele operatoren en gelijkheidsoperatoren resulteren in een Booleaanse waarde. Ze hebben echter verschillende conversieregels afhankelijk van de oorspronkelijke datatypen van hun operanden, zoals weergegeven in deze tabel.

Operand Relationele operator Gelijkheidsoperator
Beide operanden zijn knoopverzamelingen. WAAR als en slechts als er een knoop in de ene set en een knoop in de tweede verzameling is, zodat de vergelijking van hun stringwaarden WAAR is. Zelfde.
De ene is een knoopset, de andere een string. WAAR als en slechts als er een knoop in de knoopset-verzameling is zodanig dat, wanneer omgezet naar getal, de vergelijking ervan met de string die is omgezet naar getal WAAR is. WAAR als en slechts als er een knoop in de knoopset-verzameling is zodanig dat, wanneer deze wordt omgezet in string, de vergelijking ervan met de string WAAR is.
De ene is een knoopset, de andere een getal. WAAR als en slechts als er een knoop in de knooppuntset is zodanig dat, wanneer omgezet naar getal, de vergelijking ervan met het getal WAAR is. Zelfde.
De ene is een node-set, de andere een booleaan. WAAR als en slechts als er een knoop in de knooppuntset is zodanig dat, wanneer deze wordt omgezet naar booleans en vervolgens naar getal, de vergelijking ervan met de booleaanse die naar nummer is omgezet WAAR is. WAAR als en slechts als er een knoop in de knoopset-verzameling is zodanig dat, wanneer deze wordt omgezet naar booleaan, de vergelijking ervan met de booleaanse is WAAR.
Geen van beide is een node-set. Zet beide operanden om in getal en vergelijk dan. Converteer beide operanden naar een gemeenschappelijke type en vergelijk dan. Converteer naar booleans als een van beide booleans is, getal als een van beide getal is; Anders converteer naar snaar.

Opmerking

Omdat XPath-relationele operatoren hun operanden altijd omzetten naar getal, zijn snaarvergelijkingen niet mogelijk. Om datumvergelijkingen op te nemen, biedt SQL Server 2000 deze variatie aan de XPath-specificatie: wanneer een relationele operator een string met een string vergelijkt, een node-set met een string, of een string-waarde node-set met een string-waarde, wordt een stringvergelijking uitgevoerd (geen getalvergelijking).

Node-Set Bekeringen

Node-set-conversies zijn niet altijd intuïtief. Een node-set wordt omgezet in een string door alleen de stringwaarde van de eerste knoop in de set te nemen. Een node-set wordt omgezet naar nummer door deze om te zetten in string, en vervolgens naar string. Een node-set wordt omgezet naar booleans door te testen op het bestaan ervan.

Opmerking

SQL Server voert geen positionele selectie uit op node-sets: bijvoorbeeld, de XPath-query Customer[3] betekent de derde klant; dit type positionele selectie wordt niet ondersteund in SQL Server. Daarom zijn de node-set-to-string of node-set-to-number conversies zoals beschreven door de XPath-specificatie niet geïmplementeerd. SQL Server gebruikt "any" semantiek waar de XPath-specificatie "first" semantiek specificeert. Op basis van de W3C XPath-specificatie selecteert de XPath-query Order[OrderDetail/@UnitPrice > 10.0] bijvoorbeeld die bestellingen met de eerste OrderDetail die een UnitPrice groter dan 10,0 heeft. In SQL Server selecteert deze XPath-query die orders met elke OrderDetail die een UnitPrice groter dan 10,0 heeft.

De omzetting naar booleans genereert een existentietest; daarom is de XPath-query Products[@Discontinued=true()] equivalent aan de SQL-expressie "Products.Discontinued is not null", en niet aan de SQL-expressie "Products.Discontinued = 1". Om de query equivalent te maken aan de laatste SQL-expressie, converteer je eerst de node-set naar een niet-booleaans type, zoals getal. Bijvoorbeeld: Products[number(@Discontinued) = true()].

Omdat de meeste operatoren WAAR zijn als WAAR als ze WAAR zijn voor een of één van de knooppunten in de knoopset, evalueren deze operaties altijd naar FALSE als de knooppuntset leeg is. Dus, als A leeg is, zijn zowel A = B als A != B ONJUIST, en not(A=B) en not(A!=B) en WAAR.

Gewoonlijk bestaat er een attribuut of element dat aan een kolom wordt gekoppeld als de waarde van die kolom in de database niet nul is. Elementen die op rijen worden gemapt bestaan als er een van hun kinderen bestaat.

Opmerking

Elementen geannoteerd met is-constant bestaan altijd. Bijgevolg kunnen XPath-predicaten niet worden gebruikt op is-constante elementen.

Wanneer een node-set wordt omgezet naar string of nummer, wordt het XDR-type (indien aanwezig) geïnspecteerd in het geannoteerde schema en dat type wordt gebruikt om de vereiste conversie te bepalen.

Mapping van XDR-datatypes aan XPath-datatypes

Het XPath-datatype van een node is afgeleid van het XDR-datatype in het schema, zoals weergegeven in de volgende tabel (de node EmployeeID wordt gebruikt voor illustratieve doeleinden).

XDR-datatype Equivalent

XPath-datatype
Gebruikte SQL Server-conversie
Nonebin.base64bin.hex N/A NoneEmployeeID
booleaan booleaan CONVERT(bit, EmployeeID)
Nummer, int, float, i1, i2, i4, i8, r4, r8ui1, ui2, ui4, ui8 nummer CONVERT(float(53), WerknemersID)
id, idref, idrefsentity, entiteiten, enumerationnotation, nmtoken, nmtokens, chardate, Timedate, Time.tz, string, uri, uuid touw CONVERT(nvarchar(4000), WerknemersID, 126)
fixed14.4 N/A(Er is geen datatype in XPath dat equivalent is aan het vaste14.4 XDR-datatype) CONVERT(geld, WerknemersID)
date touw LINKS(CONVERT(nvarchar(4000), EmployeeID, 126), 10)
time

time.tz
touw SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24)

De datum- en tijdconversies zijn ontworpen om te werken, ongeacht of de waarde in de database wordt opgeslagen met het SQL Serverdatetime-datatype of een string. Let op dat hetdatatype data van SQL Server datetime geen tijdzone gebruikt en een kleinere precisie heeft dan het datatype XML time . Om het tijdzone-datatype of extra precisie op te nemen, sla je de data op in SQL Server met behulp van een stringtype .

Wanneer een node wordt omgezet van zijn XDR-datatype naar het XPath-datatype, is soms extra conversie nodig (van het ene XPath-datatype naar het andere XPath-datatype). Overweeg bijvoorbeeld deze XPath-query:

(@m + 3) = 4  

Als @m het datatype fixed14.4 XDR is, wordt de conversie van XDR-datatype naar XPath-datatype uitgevoerd met behulp van:

CONVERT(money, m)  

Bij deze conversie wordt de node m omgezet van fixed14.4 naar money. Het toevoegen van de waarde van 3 vereist echter extra conversie:

CONVERT(float(CONVERT(money, m))  

De XPath-expressie wordt geëvalueerd als:

CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)  

Zoals weergegeven in de volgende tabel, is dit dezelfde conversie die wordt toegepast voor andere XPath-expressies (zoals literalen of samengestelde uitdrukkingen).

X is onbekend X is een snaar X is het getal X is booleans
string(X) CONVERT (nvarchar(4000), X, 126) - CONVERT (nvarchar(4000), X, 126) GEVAL WANNEER X DAN NIET WAAR ANDERS Onwaar. EINDE
getal(X) CONVERT (float(53), X) CONVERT (float(53), X) - GEVAL WANNEER X DAN 1 ANDERS 0 EINDIGT
Booleaan(X) - LEN(X) > 0 X != 0 -

Voorbeelden

Eén. Converteer een datatype in een XPath-query

In de volgende XPath-query, gespecificeerd op basis van een geannoteerd XSD-schema, selecteert de query alle Employee-nodes met de EmployeeID-attribuutwaarde E-1, waarbij "E-" het voorvoegsel is dat wordt gespecificeerd met de sql:id-prefix-annotatie.

Employee[@EmployeeID="E-1"]

Het predicaat in de query is equivalent aan de SQL-expressie:

N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'

Omdat EmployeeID een van de id (idref, idrefs, nmtoken, nmtokens, enzovoort) datatypewaarden is in het XSD-schema, wordt EmployeeID omgezet naar de reeks XPath-datatype met behulp van de eerder beschreven conversieregels.

CONVERT(nvarchar(4000), Employees.EmployeeID, 126)

Het voorvoegsel "E-" wordt aan de string toegevoegd, en het resultaat wordt vervolgens vergeleken met N'E-1'.

B. Voer meerdere datatypeconversies uit in een XPath-query

Beschouw deze XPath-query gespecificeerd op basis van een geannoteerd XSD-schema: OrderDetail[@UnitPrice * @OrderQty > 98]

Deze XPath-query geeft alle <OrderDetail-elementen> terug die voldoen aan het predicaat @UnitPrice * @OrderQty > 98. Als de UnitPrice wordt geannoteerd met een vast datatype 14.4 in het geannoteerde schema, is dit predicaat equivalent aan de SQL-expressie:

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)

Bij het omzetten van de waarden in de XPath-query wordt het XDR-datatype bij de eerste conversie omgezet naar het XPath-datatype. Omdat het XSD-datatype van UnitPricevast14.4 is, zoals beschreven in de vorige tabel, is dit de eerste gebruikte conversie:

CONVERT(money, OrderDetail.UnitPrice))   

Omdat de rekenkundige operatoren hun operanden omzetten naar het getal XPath-datatype, wordt de tweede conversie (van het ene XPath-datatype naar het andere XPath-datatype) toegepast waarbij de waarde wordt omgezet naar float(53) (float(53) ligt dicht bij het XPath-getal datatype):

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice))   

Aangenomen dat het OrderQty-attribuut geen XSD-datatype heeft, wordt OrderQty in één enkele conversie omgezet naar een XPath-datatype met het getal :

CONVERT(float(53), OrderDetail.OrderQty)  

Op dezelfde manier wordt de waarde 98 omgezet naar het datatype XPath:

CONVERT(float(53), 98)  

Opmerking

Als het XSD-datatype dat in het schema wordt gebruikt incompatibel is met het onderliggende SQL Server-datatype in de database, of als een onmogelijke XPath-datatypeconversie wordt uitgevoerd, kan SQL Server een foutmelding geven. Als bijvoorbeeld het EmployeeID-attribuut wordt geannoteerd met id-voorvoegselannotatie , genereert de XPath Employee[@EmployeeID=1] een foutmelding, omdat EmployeeID de id-voorvoegsel-annotatie heeft en niet kan worden omgezet naar nummer.