Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
van toepassing op:SQL Server-
In XQuery kunt u de directe en berekende constructors gebruiken om XML-structuren in een query te maken.
Notitie
Er is geen verschil tussen de directe en berekende constructors.
Directe constructors gebruiken
Wanneer u directe constructors gebruikt, geeft u XML-achtige syntaxis op wanneer u de XML maakt. De volgende voorbeelden illustreren de XML-constructie door de directe constructors.
Elementen samenstellen
Bij het gebruik van XML-notaties kunt u elementen samenstellen. In het volgende voorbeeld wordt de directe elementconstructorexpressie gebruikt en wordt een <ProductModel> element gemaakt. Het samengestelde element heeft drie onderliggende elementen
Een tekstknooppunt.
Twee elementknooppunten en
<Summary><Features>.Het
<Summary>element heeft één onderliggend tekstknooppunt waarvan de waarde is"Some description".Het
<Features>element heeft drie elementknooppunten, onderliggende,<Color>,<Weight>en<Warranty>. Elk van deze knooppunten heeft één onderliggend tekstknooppunt en heeft respectievelijk de waardenRed,25respectievelijk2 years parts and labor.
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>');
Dit is de resulterende 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>
Hoewel het maken van elementen uit constante expressies, zoals in dit voorbeeld wordt weergegeven, nuttig is, is de echte kracht van deze XQuery-taalfunctie de mogelijkheid om XML te maken waarmee gegevens dynamisch uit een database worden geëxtraheerd. U kunt accolades gebruiken om query-expressies op te geven. In de resulterende XML wordt de expressie vervangen door de bijbehorende waarde. Met de volgende query wordt bijvoorbeeld een <NewRoot> element samengesteld met één onderliggend element (<e>). De waarde van het element <e> wordt berekend door een padexpressie in accolades op te geven ("{ ... }").
DECLARE @x AS XML;
SET @x = '<root>5</root>';
SELECT @x.query('<NewRoot><e> { /root } </e></NewRoot>');
De accolades fungeren als contextwisseltokens en schakelen tussen de query van XML-constructie en de evaluatie van query's. In dit geval wordt de XQuery-padexpressie in de accolades, /root, geëvalueerd en worden de resultaten vervangen.
Dit is het resultaat:
<NewRoot>
<e>
<root>5</root>
</e>
</NewRoot>
De volgende query is vergelijkbaar met de vorige. De expressie in de accolades geeft echter de data() functie op om de atomische waarde van het <root> element op te halen en toe te wijzen aan het samengestelde element, <e>.
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;
Dit is het resultaat:
<NewRoot>
<e>5</e>
</NewRoot>
Als u de accolades wilt gebruiken als onderdeel van uw tekst in plaats van contextwisselingstokens, kunt u deze escapen als }} of {{, zoals wordt weergegeven in dit voorbeeld:
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;
Dit is het resultaat:
<NewRoot> Hello, I can use { and } as part of my text</NewRoot>
De volgende query is een ander voorbeeld van het maken van elementen met behulp van de directe elementconstructor. De waarde van het <FirstLocation> element wordt ook verkregen door de expressie in de accolades uit te voeren. De query-expressie retourneert de productiestappen op de eerste werkcentrumlocatie in de kolom Instructies van de tabel Production.ProductModel.
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;
Dit is het resultaat:
<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>
Elementinhoud in XML-constructie
In het volgende voorbeeld ziet u het gedrag van de expressies in het samenstellen van elementinhoud met behulp van de direct elementconstructor. In het volgende voorbeeld geeft de constructor van het directe element één expressie op. Voor deze expressie wordt één tekstknooppunt gemaakt in de resulterende XML.
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>');
De atomische waardereeks die het resultaat is van de expressie-evaluatie wordt toegevoegd aan het tekstknooppunt met een spatie tussen de aangrenzende atomische waarden, zoals wordt weergegeven in het resultaat. Het samengestelde element heeft één onderliggend element. Dit is een tekstknooppunt dat de waarde bevat die in het resultaat wordt weergegeven.
<result>This is step 1 This is step 2 This is step 3</result>
Als u in plaats van één expressie drie afzonderlijke expressies opgeeft die drie tekstknooppunten genereren, worden de aangrenzende tekstknooppunten samengevoegd in één tekstknooppunt, door samenvoeging, in de resulterende XML.
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>');
Het knooppunt voor het samengestelde element heeft één onderliggend element. Dit is een tekstknooppunt dat de waarde bevat die in het resultaat wordt weergegeven.
<result>This is step 1This is step 2This is step 3</result>
Kenmerken samenstellen
Wanneer u elementen maakt met behulp van de direct elementconstructor, kunt u ook kenmerken van het element opgeven met behulp van XML-achtige syntaxis, zoals wordt weergegeven in dit voorbeeld:
DECLARE @x AS XML;
SET @x = '';
SELECT @x.query('<ProductModel ProductModelID="111">;
This is product model catalog description.
<Summary>Some description</Summary>
</ProductModel>');
Dit is de resulterende XML:
<ProductModel ProductModelID="111">
This is product model catalog description.
<Summary>Some description</Summary>
</ProductModel>
Het samengestelde element <ProductModel> heeft een kenmerk ProductModelID en deze onderliggende knooppunten:
Een tekstknooppunt,
This is product model catalog description.Een elementknooppunt,
<Summary>. Dit knooppunt heeft één onderliggend tekstknooppunt,Some description.
Wanneer u een kenmerk maakt, kunt u de waarde opgeven met een expressie in accolades. In dit geval wordt het resultaat van de expressie geretourneerd als de kenmerkwaarde.
In het volgende voorbeeld is de data() functie niet strikt vereist. Omdat u de expressiewaarde aan een kenmerk toewijst, data() wordt impliciet toegepast om de getypte waarde van de opgegeven expressie op te halen.
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;
Dit is het resultaat:
<NewRoot attr="5" />
Hieronder volgt een ander voorbeeld waarin expressies worden opgegeven voor locationID- en SetupHrs-kenmerkconstructie. Deze expressies worden geëvalueerd op basis van de XML in de kolom Instructie. De getypte waarde van de expressie wordt toegewezen aan de kenmerken.
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;
Dit is het gedeeltelijke resultaat:
<FirstLocation LocationID="10" SetupHours="0.5" >
<AWMI:step ...
</AWMI:step>
...
</FirstLocation>
Implementatiebeperkingen
Dit zijn de beperkingen:
Kenmerkexpressies voor meerdere of gemengde kenmerken (tekenreeks en XQuery-expressie) worden niet ondersteund. Zoals in de volgende query wordt weergegeven, maakt u bijvoorbeeld XML waarbij
Itemeen constante is en de waarde5wordt verkregen door een query-expressie te evalueren:<a attr="Item 5" />De volgende query retourneert een fout, omdat u een constante tekenreeks combineert met een expressie ({/x}) en dit wordt niet ondersteund:
DECLARE @x AS XML; SET @x = '<x>5</x>'; SELECT @x.query('<a attr="Item {/x}"/>');In dit geval hebt u de volgende opties:
De kenmerkwaarde vormen door de samenvoeging van twee atomische waarden. Deze atomische waarden worden geserialiseerd in de kenmerkwaarde met een spatie tussen de atomische waarden:
SELECT @x.query('<a attr="{''Item'', data(/x)}"/>');Dit is het resultaat:
<a attr="Item 5" />Gebruik de samenvoegfunctie om de twee tekenreeksargumenten samen te voegen in de resulterende kenmerkwaarde:
SELECT @x.query('<a attr="{concat(''Item'', /x[1])}"/>');In dit geval is er geen spatie toegevoegd tussen de twee tekenreekswaarden. Als u een spatie tussen de twee waarden wilt, moet u deze expliciet opgeven.
Dit is het resultaat:
<a attr="Item5" />
Meerdere expressies als kenmerkwaarde worden niet ondersteund. De volgende query retourneert bijvoorbeeld een fout:
DECLARE @x AS XML; SET @x = '<x>5</x>'; SELECT @x.query('<a attr="{/x}{/x}"/>');Heterogene reeksen worden niet ondersteund. Elke poging om een heterogene reeks toe te wijzen als een kenmerkwaarde retourneert een fout, zoals wordt weergegeven in het volgende voorbeeld. In dit voorbeeld wordt een heterogene reeks, een tekenreeks 'Item' en een element
<x>, opgegeven als de kenmerkwaarde:DECLARE @x AS XML; SET @x = '<x>5</x>'; SELECT @x.query('<a attr="{''Item'', /x }" />');Als u de
data()functie toepast, werkt de query omdat deze de atomische waarde van de expressie ophaalt,/xdie wordt samengevoegd met de tekenreeks. Hieronder volgt een reeks atomische waarden:SELECT @x.query('<a attr="{''Item'', data(/x)}"/>');Dit is het resultaat:
<a attr="Item 5" />Volgorde van kenmerkknooppunten wordt afgedwongen tijdens serialisatie in plaats van tijdens het controleren van het statische type. De volgende query mislukt bijvoorbeeld omdat er wordt geprobeerd een kenmerk toe te voegen na een niet-kenmerkknooppunt.
SELECT CONVERT (XML, '').query(' element x { attribute att { "pass" }, element y { "Element text" }, attribute att2 { "fail" } } '); GODe vorige query retourneert de volgende fout:
XML well-formedness check: Attribute cannot appear outside of element declaration. Rewrite your XQuery so it returns well-formed XML.
Naamruimten toevoegen
Wanneer u XML maakt met behulp van de directe constructors, kunnen het samengestelde element en de kenmerknamen worden gekwalificeerd met behulp van een voorvoegsel voor de naamruimte. U kunt het voorvoegsel op de volgende manieren aan de naamruimte binden:
- Met behulp van een naamruimtedeclaratiekenmerk.
- Met behulp van de
WITH XMLNAMESPACEScomponent. - In het XQuery-prolog.
Een naamruimtedeclaratiekenmerk gebruiken om naamruimten toe te voegen
In het volgende voorbeeld wordt een naamruimtedeclaratiekenmerk gebruikt in de constructie van het element <a> om een standaardnaamruimte te declareren. Met de constructie van het onderliggende element <b> wordt de declaratie van de standaardnaamruimte ongedaan gemaakt die in het bovenliggende element is gedeclareerd.
DECLARE @x AS XML;
SET @x = '<x>5</x>';
SELECT @x.query('
<a xmlns="a">
<b xmlns=""/>
</a>');
Dit is het resultaat:
<a xmlns="a">
<b xmlns="" />
</a>
U kunt een voorvoegsel toewijzen aan de naamruimte. Het voorvoegsel wordt opgegeven in de constructie van het element <a>.
DECLARE @x AS XML;
SET @x = '<x>5</x>';
SELECT @x.query('
<x:a xmlns:x="a">
<b/>
</x:a>');
Dit is het resultaat:
<x:a xmlns:x="a">
<b />
</x:a>
U kunt een standaardnaamruimte in de XML-constructie ongedaan maken, maar u kunt een naamruimtevoorvoegsel niet ongedaan maken. De volgende query retourneert een fout, omdat u een voorvoegsel niet kunt declareren zoals opgegeven in de constructie van het element <b>.
DECLARE @x AS XML;
SET @x = '<x>5</x>';
SELECT @x.query('
<x:a xmlns:x="a">
<b xmlns:x=""/>
</x:a>');
De zojuist samengestelde naamruimte is beschikbaar voor gebruik in de query. De volgende query declareert bijvoorbeeld een naamruimte bij het maken van het element <FirstLocation>en geeft het voorvoegsel op in de expressies voor de kenmerkwaarden LocationID en 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;
Als u een nieuw naamruimtevoorvoegsel maakt, overschrijft u alle bestaande naamruimtedeclaraties voor dit voorvoegsel. De declaratie van de naamruimte, in de queryprolog, AWMI="https://someURI"wordt bijvoorbeeld overschreven door de naamruimtedeclaratie in het <FirstLocation> element.
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;
Een prolog gebruiken om naamruimten toe te voegen
In dit voorbeeld ziet u hoe naamruimten kunnen worden toegevoegd aan de samengestelde XML. Een standaardnaamruimte wordt gedeclareerd in het queryprolog.
DECLARE @x AS XML;
SET @x = '<x>5</x>';
SELECT @x.query('
declare default element namespace "a";
<a><b xmlns=""/></a>');
In de constructie van het element <b>wordt het kenmerk naamruimtedeclaratie opgegeven met een lege tekenreeks als waarde. Hiermee wordt de standaardnaamruimte gedeclareerd die in het bovenliggende item is gedeclareerd.
Dit is het resultaat:
<a xmlns="a">
<b xmlns="" />
</a>
Verwerking van XML-constructie en witruimte
De elementinhoud in xml-constructie kan witruimtetekens bevatten. Deze tekens worden op de volgende manieren verwerkt:
De spatietekens in naamruimte-URI's worden behandeld als het XSD-type
anyURI. Dit is de manier waarop ze worden verwerkt:- Alle witruimtetekens aan het begin en einde worden ingekort.
- Waarden voor interne spaties worden samengevouwen in één spatie
De regelfeedtekens in de kenmerkinhoud worden vervangen door spaties. Alle andere witruimtetekens blijven ongewijzigd.
De witruimte binnen elementen blijft behouden.
In het volgende voorbeeld ziet u de verwerking van witruimte in XML-constructie:
-- 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;
Dit is het resultaat:
-- result
<test attr="<test attr=" my test attr value "><a>
This is a
test
</a></test>
"><a>
This is a
test
</a></test>
Andere directe XML-constructors
De constructors voor het verwerken van instructies en XML-opmerkingen gebruiken dezelfde syntaxis als de bijbehorende XML-constructsyntaxis. Berekende constructors voor tekstknooppunten worden ook ondersteund, maar worden voornamelijk gebruikt om XML DML tekstknooppunten te maken.
Notitie
Zie het specifieke voorbeeld in insert (XML DML) voor een voorbeeld van het gebruik van een expliciete tekstknooppuntconstructor.
In de volgende query bevat de samengestelde XML een element, twee kenmerken, een opmerking en een verwerkingsinstructie. Er wordt een komma gebruikt vóór de <FirstLocation>, omdat er een reeks wordt samengesteld.
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;
Dit is het gedeeltelijke resultaat:
<?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>
Berekende constructors gebruiken
In dit geval geeft u de trefwoorden op waarmee het type knooppunt wordt geïdentificeerd dat u wilt maken. Alleen de volgende trefwoorden worden ondersteund:
- element
- attribuut
- Sms
Voor element- en kenmerkknooppunten worden deze trefwoorden gevolgd door de naam van het knooppunt en ook door de expressie, tussen accolades, waarmee de inhoud voor dat knooppunt wordt gegenereerd. In het volgende voorbeeld maakt u deze XML:
<root>
<ProductModel PID="5">Some text <summary>Some Summary</summary></ProductModel>
</root>
Dit is de query die gebruikmaakt van berekende constructors genereren de XML:
DECLARE @x AS XML;
SET @x = '';
SELECT @x.query('element root
{
element ProductModel
{
attribute PID { 5 },
text{"Some text "},
element summary { "Some Summary" }
}
} ');
De expressie waarmee de knooppuntinhoud wordt gegenereerd, kan een query-expressie opgeven.
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 }
}
} ');
Met de berekende element- en kenmerkconstructors, zoals gedefinieerd in de XQuery-specificatie, kunt u de namen van knooppunten berekenen. Wanneer u directe constructors in SQL Server gebruikt, moeten de knooppuntnamen, zoals element en kenmerk, worden opgegeven als constante letterlijke waarden. Daarom is er geen verschil in de directe constructors en berekende constructors voor elementen en kenmerken.
In het volgende voorbeeld wordt de inhoud voor de samengestelde knooppunten verkregen uit de XML-productie-instructies die zijn opgeslagen in de kolom Instructies van het xml- gegevenstype in de tabel 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;
Dit is het gedeeltelijke resultaat:
<FirstLocation LocationID="10">
<AllTheSteps>
<AWMI:step> ... </AWMI:step>
<AWMI:step> ... </AWMI:step>
...
</AllTheSteps>
</FirstLocation>
Andere implementatiebeperkingen
Berekende kenmerkconstructors kunnen niet worden gebruikt om een nieuwe naamruimte te declareren. De volgende berekende constructors worden ook niet ondersteund in SQL Server:
- Berekende documentknooppuntconstructors
- Berekende verwerkingsinstructors
- Berekende opmerkingconstructors