2017-06-13 1 views
0

XML-Schema zu erhalten: (Geht davon aus, dass die XMLNAMESPACES bereits als gesetzt sind und b)Ärger mit XQuery SQL-Anweisung korrekt Eltern/Kind-Wert

<Layer1 xmlns="a"> 
    <Layer2 xmlns="b"> 
    <Layer3> 
     <id>val1</id> 
     <data>False</data> 
    </Layer3> 
    <Layer3> 
     <id>val2</id> 
     <data>True</data> 
    </Layer3> 
    </Layer2> 
</Layer1> 

Ich verwende dieses Bit von SQL zu versuchen, meine accomplinsh Aufgabe.

ITEM.value('(/a:Layer1/b:Layer2/b:Layer3)[1]', 'varchar(max)') AS ReturnValue 

Was ich versuche, ist nur die wahren Werte, wo id = 'val2 UND data = 'True'. Etwas wie dieses:

ITEM.value('(/a:Layer1/b:Layer2/b:Layer3[id="val2" and data="True"]/b:data)[0]', 'varchar(max)') AS ReturnValue 

Aus irgendeinem Grund gibt das oben genannte null zurück. Ich würde annehmen, dass es sich um einen Syntaxfehler handelt.

In dieser Abfrage möchte ich den Wert als True von einem Layer3 Parent zurückgegeben werden, wo die ID und Daten die Bedingungen folgen. Ich würde mich über jede Hilfe freuen und Ihnen im Voraus danken.

Antwort

0

Von Ihrem Code, den ich nehmen, dass diese SQL-Server ist ...

Ihre XML definiert einen Standard-Namespace für den ersten Knoten <Layer1> und wieder ein Standard-Namespace für die <Layer2>.

Das bedeutet, dass alle Elemente unter <Layer2> in diesem neuen Standardnamespace sind.

Ihr Code fehlt die Namespaces hier [id="val2" and data="True"], aber ich verstehe nicht wirklich, was Sie tatsächlich versuchen zu erreichen ...

DECLARE @ITEM XML= 
N'<Layer1 xmlns="a"> 
    <Layer2 xmlns="b"> 
    <Layer3> 
     <id>val1</id> 
     <data>False</data> 
    </Layer3> 
    <Layer3> 
     <id>val2</id> 
     <data>True</data> 
    </Layer3> 
    </Layer2> 
</Layer1>'; 

--Dieser Abfrage den Wert „True“ innerhalb <data> unten ein finden <Layer3>, wo die <id> „val2“ ist:

WITH XMLNAMESPACES('a' AS a,'b' AS b) 
SELECT @ITEM.value('(/a:Layer1/b:Layer2/b:Layer3[b:id="val2"]/b:data/text())[1]', 'varchar(max)'); 

Sie könnten eine *: vor jedem Gebrauch und einen beliebigen Namen ein Namespace-Platzhalter zu verwenden:

SELECT @ITEM.value('(/*:Layer1/*:Layer2/*:Layer3[*:id="val2"]/*:data/text())[1]', 'varchar(max)'); 

Ein weiterer Ansatz war Ihr inneren Standard ns so zu definieren, die weniger tippen müssen:

WITH XMLNAMESPACES('a' AS a, DEFAULT 'b') 
SELECT @ITEM.value('(/a:Layer1/Layer2/Layer3[id="val2"]/data/text())[1]', 'varchar(max)');