modifier (replace) XML pour les conditions

Je veux replace la valeur dans une balise d'élément, en fonction de sa valeur, ainsi que la valeur d'un autre élément (au même niveau que cet élément), les deux éléments étant partout dans la même balise parent (Chaque balise parent est unique en raison de son propre atsortingbut ID). Je veux faire le changement à divers endroits de cette variable XML, dans une procédure stockée.

Étant un premier temporisateur à ceci, je suis coincé avec comment je pourrais modifier les éléments tout au long du xml. Les deux éléments sont présents dans le même élément parent partout dans le document et chacun de ces balises parent possède un atsortingbut ID unique.

Toute suggestion serait d'une grande aide. Des liens vers des documents sur la façon de mélanger et de faire correspondre "value ()", "modify ()", etc. seront également utiles.

DECLARE @xml xml = ' <SemanticModel xmlns="schemas.microsoft.com/sqlserver/2004/10/semanticmodeling"; xmlns:xsi="w3.org/2001/XMLSchema-instance"; xmlns:xsd="w3.org/2001/XMLSchema"; ID="G1"> <Entities> <Entity ID="E1"> <Fields> <Atsortingbute ID="A1"> <Name>AAAA</Name> <DataType>Float</DataType> <Format>n0</Format> <Column Name="AAAA_ID" /> </Atsortingbute> <Atsortingbute ID="A2"> <Name>BBBB</Name> <DataType>Integer</DataType> <Format>n0</Format> <Column Name="BBBB_ID" /> </Atsortingbute> <Atsortingbute ID="A3"> <Name>KKKK</Name> <Variations> <Atsortingbute ID="A4"> <Name>CCCC</Name> <DataType>Float</DataType> <Format>n0</Format> </Atsortingbute> <Atsortingbute ID="A5"> <Name>AAAA</Name> <DataType>Float</DataType> <Format>n0</Format> </Atsortingbute> </Variations> <Name>AAAA</Name> <DataType>Float</DataType> <Format>n0</Format> </Atsortingbute> </Fields> </Entity> </Entities>' DECLARE @i int = 0 ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/10/semanticmodeling' as dm, 'http://schemas.microsoft.com/analysisservices/2003/engine' as dsv, 'http://w3.org/2001/XMLSchema' as xs ) select @i = @xml.value('count(//dm:Atsortingbute[dm:DataType="Float" and dm:Format="n0"]/dm:Format)', 'int') select @i while @i > 0 begin set @xml.modify(' replace value of (//dm:Atsortingbute[dm:DataType="Float" and dm:Format="n0"]/dm:Format/text())[1] with "f2" ') set @i = @i - 1 end select @xml 

Je veux replace la valeur de format "n0" par "f2" pour tous les attributes dont la valeur de format est "n0" et DataType est "Float".

-Je vous remercie

il n'est pas possible de replace plusieurs valeurs à la fois dans XML dans SQL Server, il existe plusieurs options:

  • utiliser la boucle et mettre à jour les attributes un par un
  • split datatables en variable table / table temporaire, mettre à jour, puis merge en un seul xml
  • utilise xquery pour rebuild xml

Je pense que la bonne façon pour vous serait la solution de boucle:

 select @i = @data.value('count(//Atsortingbute[DataType="Float" and Format="n0"]/Format)', 'int') while @i > 0 begin set @data.modify(' replace value of (//Atsortingbute[DataType="Float" and Format="n0"]/Format/text())[1] with "f2" ') set @i = @i - 1 end 

sql fiddle démo


Si votre file XML contient des namespaces, la manière la plus simple de mettre à jour serait de déclarer l'espace de noms default :

 ;with xmlnamespaces(default 'schemas.microsoft.com/sqlserver/2004/10/semanticmodeling') select @i = @xml.value('count(//Atsortingbute[DataType="Float" and Format="n0"]/Format)', 'int') while @i > 0 begin set @xml.modify(' declare default element namespace "schemas.microsoft.com/sqlserver/2004/10/semanticmodeling"; replace value of (//Atsortingbute[DataType="Float" and Format="n0"]/Format/text())[1] with "f2" ') set @i = @i - 1 end select @xml