2012-12-16 4 views
6

Ich verwende SQL Server 2008 und ich möchte XML-Elemente abrufen und das Element selbst und seine Attribute ohne Unterelemente und ohne den Text() zurückgeben. Zum Beispiel die folgende XML hat vier Knoten (doc, Apfel, b, Banane):Abrufen eines Elements ohne Unterelemente in SQL Server

<doc> 
<apple type="bramley"> tasty <b>yum!</b> </apple> 
<banana color="yellow" shape="bendy"> nice in smoothies </banana> 
</doc> 

Ich mag würde zurückkehren:

<doc/> 
<apple type="bramley"/> 
<b/> 
<banana color="yellow" shape="bendy"/> 

zB doc sollte ohne Unterknoten zurückgegeben werden und Apple sollte ohne den b Unterknoten zurückgegeben werden. Aber das Problem ist, wenn ich die SQL Server-Knoten und die Abfrage-Methode verwende, kann ich die Unterknoten nicht entfernen. Verwenden von SQL Server 2008 die nächste, die ich habe, ist:

declare @x xml = '<doc> 
    <apple type="bramley"> tasty <b>yum!</b> </apple> 
    <banana color="yellow" shape="bendy"> nice in smoothies </banana> 
</doc>'; 

select 
    c.query('local-name(.)') as Node, 
    c.query('for $e in . return <xx> {$e/@*} </xx>') as Attr 
from @x.nodes('//*') as T(c); 

Dieser den Namen jedes Knotens wird (unter Verwendung von local-name) und die Attribute des Knotens und kehrt:

Node Attr 
---- ---- 
doc  <xx /> 
apple <xx type="bramley" /> 
b  <xx /> 
banana <xx color="yellow" shape="bendy" /> 

Ich weiß, ich kann Verarbeite dieses Ergebnis, konvertiere Attr in varchar, ersetze xx durch die Spalte Node und konvertiere zurück nach XML. Aber gibt es einen einfacheren Weg ohne String-Manipulation?

PS: Wenn es hilft, ich habe nichts dagegen, wenn die Lösung SQL Server 2008 oder SQL Server verwendet 2012.

Antwort

1

Normalerweise würden Sie Elementkonstruktion mit dynamischem Tag-Namen verwenden, aber SQL Server unterstützt diese Funktion nicht :

declare @x xml = '<doc> 
    <apple type="bramley"> tasty <b>yum!</b> </apple> 
    <banana color="yellow" shape="bendy"> nice in smoothies </banana> 
</doc>'; 

select 
    c.query('local-name(.)') as Node, 
    c.query('for $e in . return element { local-name($e) } { $e/@* } </xx>') as Attr 
from @x.nodes('//*') as T(c); 

Als XQuery-Update Alternative (mit SQL Server 2012 getestet), können wir alle Knoten holen (mit allen Inhalten) und löschen ihre subnotes.

DECLARE @x xml = '<doc>test 
    <apple type="bramley"> tasty <b>yum!</b> </apple> 
    <banana color="yellow" shape="bendy"> nice in smoothies </banana> 
</doc>'; 

-- Fetch all nodes 
SET @x = @x.query('//*') 
-- Delete all subnodes 
SET @x.modify('delete /*/node()') 

select 
    c.query('.') as NewNode 
from @x.nodes('/*') as T(c); 
+0

Vielen Dank! Ich werde es heute später ausprobieren – Ubercoder

+0

OK Ich versuchte es in SQL Server, aber es mag es nicht - der Fehler ist _Only konstante Ausdrücke werden für den Namen Ausdruck von berechneten Element und Attribut Konstruktoren unterstützt. Also ich denke, dass ** local-name ($ e) ** als Elementkonstruktor im SQL Server nicht erlaubt ist (dies macht den Elementkonstruktor in SQL Server nicht sehr nützlich, aber das ist eine andere Geschichte). Gibt es weitere Varianten der XQuery, die ich testen kann? – Ubercoder

+0

Scheint ein echtes Problem zu sein. [Es gibt eine Antwort auf eine andere Frage] (http://stackoverflow.com/a/4418821/695343), die String-Verkettung verwendet, um das XML zu erstellen - scheint wirklich, wirklich hässlich. "Wenn dieser Ansatz beleidigend ist, können Sie jetzt aufhören zu lesen :)" ... Sehen Sie sich Ihr Problem besser auf einer höheren Ebene an. Was ist dein eigentliches Problem, das du lösen willst? –