2016-04-05 5 views
1

abgefragt wird Ich arbeite an einem System, das Daten zwischen einem neuen Schema und einem Legacy-Schema abbildet. Unter bestimmten Umständen möchte ich ein XML-Feld aktualisieren, indem ich einen Elementknoten basierend auf einem Attributwert targetiere und eine Einfügung oder Aktualisierung auf dem Textknoten vornehme. Ich habe gearbeitet, wie Update Fälle zu behandeln, aber ich bin mit dem Einsatz Schwierigkeiten habe, das heißt, Fälle, in denen die Textknoten existieren nicht:So fügen Sie einen XML-Textknoten zu einem XML-Fragment hinzu, das durch den Attributwert

Die folgende liefert die erwarteten Ergebnisse:

DECLARE @sample xml; 
SET @sample = '<CustomFields> 
       <CustomField1 MapsTo="LegacyField1"></CustomField1> 
       <CustomField2 MapsTo="LegacyField2"></CustomField2> 
       <CustomField3 MapsTo="LegacyField3"></CustomField3> 
      </CustomFields>' 

SET @sample.modify('insert text{"new field value"} into (/CustomFields/CustomField2)[1]') 

Ergebnis:

<CustomFields> 
    <CustomField1 MapsTo="LegacyField1" /> 
    <CustomField2 MapsTo="LegacyField2">new field value</CustomField2> 
    <CustomField3 MapsTo="LegacyField3" /> 
</CustomFields> 

Allerdings, wenn ich für den Zielknoten abfragen, um den MapsTo Attributwert mit erhalte ich Fehler oder schlechte Ergebnisse:

SET @sample.modify('insert text{"new field value"} into (/CustomFields/child::node()[@MapsTo="LegacyField2"])[1]') 

Der folgende Fehler tritt auf: "XQuery [modify()]: Das Ziel von 'insert in' muss ein Element/Dokumentknoten sein, gefunden '(element (*, xdt: untyped) | Kommentar | Verarbeitungsanweisung | Text) '“

Wenn ich den Zielknoten in einem separaten Arbeitsgang wie so greifen:

DECLARE @node XML = @sample.query('/CustomFields/child::node()[@MapsTo="LegacyField2"][1]') 

bekomme ich die erwartete Knoten:

<CustomField2 MapsTo="LegacyField2" /> 

Aber wenn ich dann eine modify laufen: einfügen wie so:

SET @node.modify('insert text{"new field value"} into (self::node())[1]') 

bekomme ich folgende unerwartete Ergebnis:

<CustomField2 MapsTo="LegacyField2" />new field value 

Was ich suche, ist natürlich:

<CustomField2 MapsTo="LegacyField2">new field value</CustomField2> 

BTW: die Indexelemente "[1]" die letzten beiden Operationen scheinen überflüssig zu sein.

Ich mache wahrscheinlich einen einfachen Fehler der Syntax oder Konzeption, aber bis jetzt konnte ich es nicht sortieren. Jede Hilfe wäre sehr geschätzt. diese

Antwort

1

Check out:

DECLARE @sample xml; 
SET @sample = '<CustomFields> 
       <CustomField1 MapsTo="LegacyField1"></CustomField1> 
       <CustomField2 MapsTo="LegacyField2"></CustomField2> 
       <CustomField3 MapsTo="LegacyField3"></CustomField3> 
      </CustomFields>'; 

--directly into Element named CustomField2 
SET @sample.modify('insert text{"new field value"} into (/CustomFields/CustomField2)[1]'); 

--per named "MapsTo" into LegacyField1 
SET @sample.modify('insert text{"111"} into (/CustomFields/*[@MapsTo="LegacyField1"])[1]'); 

--per dynamically named "MapsTo" into LegacyField 
DECLARE @target VARCHAR(100)='LegacyField3'; 
SET @sample.modify('insert text{"333"} into (/CustomFields/*[@MapsTo=sql:variable("@target")])[1]'); 

SELECT @sample; 
+0

Awesome! Vielen Dank für Ihre Hilfe. Irgendwelche Erkenntnisse über den Unterschied zwischen '/ CustomFields/Kind :: Knoten() [@ MapsTo = "LegacyField1"]' und '/ CustomFields/* [@ MapsTo = "LegacyField1"]'? –

+1

@RickPutnam, eigentlich nicht ... in '.query()' scheinen sie ähnlich zu arbeiten, aber in 'modify()' führt das 'child :: node()' zu einem untypisierten Element. Im Moment habe ich nicht die Zeit, mich darauf einzulassen. Ich komme später wieder ... (oder liest vielleicht jemand anderes das?) – Shnugo

Verwandte Themen