Quelqu'un pourrait-il m'aider s'il vous plaît avec un modèle de sortie XML s'il vous plaît. Un client m'a demandé de créer un fichier de sortie XML. Ce fichier sera ensuite alimenté dans le CRM du client. C'est pourquoi, il doit correspondre exactement au modèle demandé par le client. J'ai réussi à l'appariement parfait en dehors de CDATA pour quelques champs.
vous trouverez ci-dessous la requête que vous pouvez utiliser à des fins de test. J'ai besoin de CDATA Wrap pour les champs Client et Area. J'ai également joint la sortie que je reçois en exécutant en dessous du code
If OBJECT_ID('tempdb..#Temp') is Not NULL
Drop table #Temp
CREATE TABLE #Temp
(
[ShiftDate] [date] NULL,
[Ref_Num] [varchar](20) NULL,
[Agency_Worker_Name] [varchar](100) NULL,
[Client] [varchar](100) NULL,
[Area] [VarChar] (100) Null,
[Assignment] [varchar](20) NULL,
[Contract_Start] [varchar](30) NULL,
[Contract_End] [varchar](30) NULL,
[Contract_BreakInMinutes] [varchar](10) NULL,
[Contract_Total] [varchar](30) NULL,
[Actual_Start] [varchar](30) NULL,
[Actual_End] [varchar](30) NULL,
[Actual_BreakInMinutes] [varchar](10) NULL,
[Actual_Total] [varchar](30) NULL,
[Commission] [decimal](18, 2) NULL,
[Total_Cost] [decimal](18, 2) NULL,
[Rate] [varchar](20) NULL,
[OverallCost] [decimal](18, 2) NULL,
[AgencybackingReport] [int] NULL,
[AccountCode] [varchar](20) NULL
)
Insert Into #Temp
Values
('2018-07-24',
'83076641',
'ABCD',
'ABCD',
'ABCD',
'CPA00',
'09:00',
'17:00',
'30',
'07:30',
'10:30',
'17:00',
'30',
'05:30',
'28.49',
'159.01',
'Basic',
'221.59',
'1220883',
' ABCD')
Declare @xml Int=(Select max(AgencyBackingReport) From #Temp)
select @xml As [@AgencyBackingReport],(Select
[Ref_Num] As [@reference],
[ShiftDate] as [@startdate],
Case When [AccountCode] is NULL Then 'Unknown' Else [AccountCode] End as [@accountcode],
Contract_Start As 'PlannedShift/Start',
Contract_End As 'PlannedShift/End',
Contract_BreakInMinutes As 'PlannedShift/BreakinMinutes',
Actual_Start As 'ActualShift/Start',
Actual_End As 'ActualShift/End',
Actual_BreakInMinutes As 'ActualShift/BreakinMinutes',
OverallCost As [OverallCost],
Agency_Worker_Name As 'AdditionalInformation/WorkerName',
Client As 'AdditionalInformation/Client',
Area As 'AdditionalInformation/Area',
-- ( select
-- 1 as Tag ,
-- 0 as Parent ,
-- (Select
-- Area
-- From #Temp M2
-- Where M1.Ref_Num = m2.Ref_Num)
-- As [Area!1!!CDATA]
-- for xml explicit
--) As 'AdditionalInformation/Area',
Assignment As 'AdditionalInformation/Assignment',
Commission As 'AdditionalInformation/Commission',
Total_Cost As 'AdditionalInformation/TotalCost',
Rate As 'AdditionalInformation/Rate'
From #Temp M1
for xml path('Shift'),Type)
for XML Path('Shifts'),Type
Vous semblez savoir que CDATA
est plutôt obsolète ... Si vous voulez lire quelque chose à ce sujet, vous pouvez suivre ce lien et les liens de cette réponse.
Nous devons parfois nous y tenir… Surtout si des outils tiers mal conçus le réclament. Toutefois...
La seule façon d'inclure des sections CDATA
est d'utiliser FOR XML EXPLICIT
, mais c'est plutôt maladroit.
Chaque fois que vous convertissez un XML comprenant une section CDATA
de type chaîne en XML natif, votre CDATA sera perdu et constituera un nœud text()
normal échappé correctement.
Essaye ça
DECLARE @tbl TABLE(XmlAsString NVARCHAR(MAX), NativeXml XML);
INSERT INTO @tbl
SELECT (
SELECT 1 AS Tag
,NULL AS Parent
,'test <&>' AS [SomeNode!1!!cdata]
FOR XML EXPLICIT
)
,(
SELECT 1 AS Tag
,NULL AS Parent
,'test <&>' AS [SomeNode!1!!cdata]
FOR XML EXPLICIT
);
SELECT * FROM @tbl
Le résultat
<SomeNode><![CDATA[test <&>]]></SomeNode>
<SomeNode>test <&></SomeNode>
En bref: conserver les sections CDATA vous oblige à rester en type chaîne. Peut-être un gros inconvénient ...
Si je vois cela correctement, vous voulez tout obtenir comme ci-dessus, mais
<Area><![CDATA[ABCD]]></Area>
... au lieu de
<Area>ABCD</Area>
Créez le code XML comme vous le faites ci-dessus, puis read le contenu de <Area>
et utilisez un REPLACE
au niveau de la chaîne pour modifier ce nœud dans son intégralité. Mais vous ne devez jamais reconvertir cela en XML ...
Ceci est votre XML avec la section CDATA
, pas tout à fait complet, mais vous voyez les principes:
SELECT 1 AS Tag
,NULL AS Parent
,1220883 AS [Shifts!1!AgencyBackingReport]
,NULL AS [Shift!2!reference]
,NULL AS [Shift!2!startdate]
,NULL AS [Shift!2!accountcode]
,NULL AS [PlannedShift!3!Start!Element]
,NULL AS [PlannedShift!3!End!Element]
,NULL AS [PlannedShift!3!BreakingMinutes!Element]
,NULL AS [ActualShift!4!dummy!Element] --just a dummy
,NULL AS [OverallCost!5]
,NULL AS [AdditionalInformation!6!WorkerName!Element]
,NULL AS [AdditionalInformation!6!Area!CDATA]
,NULL AS [AdditionalInformation!6!Assignment!Element]
UNION ALL
SELECT 2
,1
,NULL
,83076641
,'2018-07-24'
,'ABCD'
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
UNION ALL
SELECT 3
,2
,NULL
,NULL
,NULL
,NULL
,'09:00'
,'17:00'
,30
,NULL
,NULL
,NULL
,NULL
,NULL
UNION ALL
SELECT 4 --just a dummy
,2
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,'dummy'
,NULL
,NULL
,NULL
,NULL
UNION ALL
SELECT 5
,2
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,211.59
,NULL
,NULL
,NULL
UNION ALL
SELECT 6
,2
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,'ABCD'
,'ABCD'
,'CPA00'
FOR XML EXPLICIT
Le résultat
<Shifts AgencyBackingReport="1220883">
<Shift reference="83076641" startdate="2018-07-24" accountcode="ABCD">
<PlannedShift>
<Start>09:00</Start>
<End>17:00</End>
<BreakingMinutes>30</BreakingMinutes>
</PlannedShift>
<ActualShift>
<dummy>dummy</dummy>
</ActualShift>
<OverallCost>211.59</OverallCost>
<AdditionalInformation>
<WorkerName>ABCD</WorkerName>
<Area><![CDATA[ABCD]]></Area>
<Assignment>CPA00</Assignment>
</AdditionalInformation>
</Shift>
</Shifts>
Utilisez le FOR XML dans votre requête.
E.g: select * from table1 FOR XML AUTO
Une déclaration comme celle-ci (basée sur l'infâme):
SELECT
CustomerID as "@CustomerID",
CompanyName,
Address as "address/street",
City as "address/city",
Region as "address/region",
PostalCode as "address/Zip",
Country as "address/country",
ContactName as "contact/name",
ContactTitle as "contact/title",
Phone as "contact/phone",
Fax as "contact/fax"
FROM Customers
FOR XML PATH('Customer')