Problème méthode Value du datatype XML
Bonjour
Je reçois via des queues du service broker des messages en xml envoyé par mon serveur biztalk.
Ces messages sont formattés en Xml, avec un schéma associé.
Je dois extraire les valeurs de certains noeuds du flux XML pour aller alimenter une table de trace.
Pour cela, j'utilise la méthode Value du type XML. Le problème est que, malgré une requête XPath valide, le retour est toujous nulle.
J'ai fini par trouver que c'est la présence de l'attribut xmlns dans le noeud racine qui entrainait le problème.
Un exemple de bout de code (directement exécutable dans SSMS après copier-coller) pour illustrer mon soucis :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
declare @myXml XML
declare @actionGuid uniqueidentifier
declare @eventName varchar(100)
declare @RecvMsg nvarchar(max)
set @RecvMsg =
'<MZBEventResponseMessage xmlns="http://XXX.YYY.com/mzb/0/MZBEventResponseMessageSchema">
<rowguid>b5a5a9bd-7946-05ec-14f1-639152214a0b</rowguid>
<EventName>AcceptedBySI</EventName>
<EventState>Ok</EventState>
</MZBEventResponseMessage>'
set @myXml= Convert(Xml, @RecvMsg, 0)
set @eventName= @myXml.value('(/MZBEventResponseMessage/EventName)[1]', 'varchar(50)')
set @actionGuid = @myXml.value('(/MZBEventResponseMessage/rowguid)[1]', 'uniqueidentifier')
print isnull(@eventName, '@eventName null')
print isnull(cast(@actionGuid as varchar(50)), '@actionGuid null') |
me retourne :
Code:
1 2 3
|
@eventName null
@actionGuid null |
Si, en revanche, j'enlève l'attribut xmlns le problème disparait. Le même exemple avec l'attribut en moins : (toujours copiable-collable directement pour les St Thomas :D )
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
declare @myXml XML
declare @actionGuid uniqueidentifier
declare @eventName varchar(100)
declare @RecvMsg nvarchar(max)
set @RecvMsg =
'<MZBEventResponseMessage>
<rowguid>b5a5a9bd-7946-05ec-14f1-639152214a0b</rowguid>
<EventName>AcceptedBySI</EventName>
<EventState>Ok</EventState>
</MZBEventResponseMessage>'
set @myXml= Convert(Xml, @RecvMsg, 0)
set @eventName= @myXml.value('(/MZBEventResponseMessage/EventName)[1]', 'varchar(50)')
set @actionGuid = @myXml.value('(/MZBEventResponseMessage/rowguid)[1]', 'uniqueidentifier')
print isnull(@eventName, '@eventName null')
print isnull(cast(@actionGuid as varchar(50)), '@actionGuid null') |
me retourne bien :
Code:
1 2 3
|
AcceptedBySI
B5A5A9BD-7946-05EC-14F1-639152214A0B |
Je n'arrive pas à trouver comment modifier la syntaxe de mes requêtes XPath pour régler cela.
Je contourne pour le moment le problème de manière très sale en castant le message dans un varchar (comme dans le bout de code d'illustration) et je traite la chaine pour supprimer l'attribut xmlns puis je recaste le résultat dans un type xml,mais c'est franchement immonde.
Quelqu'un, un grand boula matari du Xpath, par exemple, a-t-il une solution ?
Merci par avance. (sachant que on ne peut pas, du moins à court terme, modifier le schéma du message).
Declare NameSpace dans requete xpath
Bonjour, pour régler ce type de problme, il est necessaire d'indiquer le NameSpace. Le code suivant modifié fonctionne correctement.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
declare @myXml XML(dbo.MZBEventResponseMessageSchema)
declare @actionGuid uniqueidentifier
declare @eventName varchar(100)
declare @RecvMsg nvarchar(max)
SET @RecvMsg =
'<MZBEventResponseMessage xmlns="http://XXX.YYY.com/mzb/0/MZBEventResponseMessageSchema">
<rowguid>b5a5a9bd-7946-05ec-14f1-639152214a0b</rowguid>
<EventName>AcceptedBySI</EventName>
<EventState>Ok</EventState>
</MZBEventResponseMessage>'
SET @myXml= Convert(Xml, @RecvMsg, 0)
SET @eventName= @myXml.value('declare namespace ns="http://XXX.YYY.com/mzb/0/MZBEventResponseMessageSchema" ; (/ns:MZBEventResponseMessage/ns:EventName)[1]', 'nvarchar(100)')
SET @actionGuid= @myXml.value('declare namespace ns="http://XXX.YYY.com/mzb/0/MZBEventResponseMessageSchema" ; (/ns:MZBEventResponseMessage/ns:rowguid)[1]', 'uniqueidentifier')
print isnull(@eventName, '@EventName null')
print isnull(@actionGuid, '@actionGuid null') |
Voila. En espérant que cela va vous aider