Pour le chemin XML dans SQL Server
-
21-09-2019 - |
Question
Remarque: J'ai résolu la majorité de ce problème, mais j'ai rencontré un accroc. Lisez en bas s'il vous plaît. Vous verrez où j'ai ajouté une section (note). Tia.
J'ai une requête de jointure assez étendue que je veux jeter à XML. Je l'ai presque fonctionné, mais il me manque un concept ici quelque part. Ma requête (abrégée) ressemble:
SELECT Campaign.CampaignId "Campaign/ID"
, Campaign.CompanyId "Campaign/CompanyID"
, Campaign.CampaignName "Campaign/Name"
...
, Audio.AudioID "Campaign/Audio/ID"
, Audio.[Name] "Campaign/Audio/Name"
...
, Video.CampaignVideosAudioMute "Campaign/Video/Audio/Mute"
, Video.CampaignVideosAudioVolume "Campaign/Video/Audio/Volume"
, Video.CampaignVideosPositionX "Campaign/Video/Position/X"
...
, Characters.CharacterID "Campaign/Characters/Character/ID"
, Characters.[Name] "Campaign/Characters/Character/Name"
...
, Element.ElementID "Campaign/Elements/Element/ID"
, Element.Editable "Campaign/Elements/Element/Editable"
...
, [Image].ImageID "Campaign/Elements/Element/Image/ID"
, [Image].[Path] "Campaign/Elements/Element/Image/Path"
...
, [Text].TextID "Campaign/Elements/Element/Text/ID"
, [Text].Value "Campaign/Elements/Element/Text/Value"
FROM vwCampaign Campaign
LEFT JOIN dbo.vwCampaignAudio Audio ON Campaign.CampaignId = Audio.CampaignId
LEFT JOIN dbo.vwCampaignCharacters Characters ON Campaign.CampaignId = Characters.CampaignId
LEFT JOIN dbo.vwCampaignVideo Video ON Campaign.CampaignId = Video.CampaignId
LEFT JOIN dbo.vwCampaignElements Element ON Campaign.CampaignId = Element.CampaignId
LEFT JOIN dbo.vwCampaignElementImage [Image] ON Element.CampaignId = [Image].CampaignId AND Element.ElementID = [Image].ElementID
LEFT JOIN dbo.vwCampaignElementText [Text] ON Element.CampaignId = [Text].CampaignId AND Element.ElementID = [Text].ElementID
WHERE Campaign.CampaignId = 10370
FOR XML PATH, ELEMENTS XSINIL
La façon dont les données fonctionnent:
- 1 rangée de campagne
- 1 ligne audio - liée à la rangée de campagne
- 1 ligne vidéo - liée à la rangée de campagne
- 1-n.
- Lignes d'élément 1-n - liées à la rangée de campagne
- 0 ou 1 lignes d'image - liées à chaque ligne d'élément
- 0 ou 1 lignes de texte - liées à chaque ligne d'élément
Le XML sort comme:
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Campaign>
<ID>10370</ID>
<CompanyID>C2811EA3-361A-411A-BB4C-816A5D6C12DB</CompanyID>
<Name>Keith01</Name>
<URL>http://kab.rivworks.com/tests/kab02.htm</URL>
<Module>Coupon</Module>
<StartDate>2009-06-29T12:05:00</StartDate>
<EndDate>2021-06-30T18:00:00</EndDate>
<Notes>Test #1</Notes>
<Meta>D7E7D735-8D64-4127-84B1-7D72FB5EDD17</Meta>
<Orientation>Half-Body Left</Orientation>
<PresentationPlayerFlashVars>config=http://cdn1.deal4it.com/rivworks/demos/skymall/skymall-coupon-3.xml</PresentationPlayerFlashVars>
<Player>
<CookieIdentity>honirjymcvzk</CookieIdentity>
<Stage>
<Top></Top>
<Left></Left>
<Height>423</Height>
<Width>500</Width>
<MarginLeft></MarginLeft>
<Container>
<Background>
<Color>0xffffff</Color>
<Image></Image>
</Background>
</Container>
</Stage>
</Player>
<Audio>
<ID xsi:nil="true" />
<Name xsi:nil="true" />
<Path xsi:nil="true" />
<Meta xsi:nil="true" />
<Genre xsi:nil="true" />
</Audio>
<Video>
<ControlbarEvent>visible</ControlbarEvent>
<Event>play</Event>
<PresentationSkin>https://widgets.rivworks.com/player/latest/rivplayer.swf</PresentationSkin>
<Audio>
<Mute>False</Mute>
<Volume>100</Volume>
</Audio>
<Position>
<X>19</X>
<Y>140</Y>
</Position>
<About>
<Text>RIV Works</Text>
<Url>http://www.deal4it.com</Url>
</About>
<Size>
<Height>266</Height>
<Width>400</Width>
</Size>
<Settings>
<Autostart>True</Autostart>
<Buffer>1</Buffer>
<DelayPlay>0</DelayPlay>
<Item>0</Item>
<Quality>True</Quality>
<Repeat>none</Repeat>
</Settings>
</Video>
<Character>
<ID>19029FFC-C1C0-4134-B813-93A9FF17C7F6</ID>
<Name>Jenna</Name>
<Actor>CD5AF2B6-C39A-4316-BFB0-D4450194EC80</Actor>
<Meta>10041662-305F-4493-ACB3-460D687306A4</Meta>
<Access>Public</Access>
<Configuration>Individual</Configuration>
<ImageThumbnail>http://cdn1.deal4it.com/rivworks/images/headshots/jenna.jpg</ImageThumbnail>
<isPublic>1</isPublic>
<Demographics>
<Age>31 - 40</Age>
<Ethnicity>Caucasian</Ethnicity>
<Gender>Female</Gender>
</Demographics>
</Character>
<Elements>
<Element>
<ID>D9B2A643-73EC-4D55-BA34-D643113CEDEA</ID>
<Editable>1</Editable>
<Meta>D5F6175C-8DC7-4F18-9A5F-E2021579498B</Meta>
<Position>
<Level>2</Level>
<X>464</X>
<Y>21</Y>
</Position>
<Image>
<ID>90FF7F5A-75EC-4FB5-81B1-B9BEC4E8A22A</ID>
<Path>http://developer.rivworks.com/images/a5b19fe8-c8d3-4588-9eac-7cdf39b52078.jpg</Path>
<Link></Link>
<Target></Target>
<Meta>97261982-2131-41F7-9E2C-ADB10E31ED20</Meta>
<Size>
<Height>16</Height>
<Width>16</Width>
</Size>
</Image>
<Text>
<ID xsi:nil="true" />
<Value xsi:nil="true" />
<Link xsi:nil="true" />
<Target xsi:nil="true" />
<Meta xsi:nil="true" />
<FontColor xsi:nil="true" />
<FontFamily xsi:nil="true" />
<FontSize xsi:nil="true" />
</Text>
</Element>
</Elements>
</Campaign>
</row>
Malheureusement, j'ai quelques problèmes avec cela.
- L'élément racine est toujours au niveau des lignes. L'élément racine doit être
- Si j'ai 3 caractères et 3 éléments, je me retrouve avec 9 Éléments radiculaires. La seule chose qui passe d'un élément racine à l'autre est quel caractère et quel élément montre. (Et aggraver cela avec chaque élément ayant 0 ou 1 textes et / ou images)
Le XML devrait sortir de quelque chose comme:
<campaign>
<ID>10370</ID>
<CompanyID>C2811EA3-361A-411A-BB4C-816A5D6C12DB</CompanyID>
<etc>...</etc>
<Characters>
<Character>
<data>...</data>
<Character>
<Character>
<data>...</data>
<Character>
</Characters>
<Elements>
<Element>
<data>...</data>
<Image>...</Image>
<Text>...</Text>
<Element>
<Element>
<data>...</data>
<Image>...</Image>
<Text>...</Text>
<Element>
</Elements>
</campaign>
De quoi ai-je besoin pour changer? Dois-je regarder une méthode différente pour créer mon XML, peut-être une sorte de clause de nidification?
Remarque: Après avoir joué et beaucoup de googling / binging, j'ai modifié ma requête afin qu'elle utilise des requêtes imbriquées. Voici à quoi ça ressemble maintenant:
SELECT Campaign.CampaignId "Campaign/ID"
, Campaign.CompanyId "Campaign/CompanyID"
, Campaign.CampaignName "Campaign/Name"
...
, Audio.AudioID "Campaign/Audio/ID"
, Audio.[Name] "Campaign/Audio/Name"
...
, Video.CampaignVideosControlbarEvent "Campaign/Video/ControlbarEvent"
, Video.CampaignVideosEvent "Campaign/Video/Event"
, (SELECT cc.CharacterID "Character/ID"
, cc.[Name] "Character/Name"
FROM dbo.vwCampaignCharacters cc
WHERE cc.CampaignID = Campaign.CampaignId
FOR XML PATH ('')
) AS "Campaign/Characters"
, (SELECT ce.ElementID "Element/ID"
, ce.Editable "Element/Editable"
, ce.Meta "Element/Meta"
, ce.PositionLevel "Element/Position/Level"
, ce.PositionX "Element/Position/X"
, ce.PositionY "Element/Position/Y"
, (SELECT cei.ImageID "Image/ID"
, cei.[Path] "Image/Path"
, cei.Link "Image/Link"
, cei.Target "Image/Target"
, cei.Meta "Image/Meta"
, cei.SizeHeight "Image/Size/Height"
, cei.SizeWidth "Image/Size/Width"
FROM dbo.vwCampaignElementImage cei
WHERE cei.CampaignID = ce.CampaignId
AND cei.ElementID = ce.ElementID
FOR XML PATH ('')
) AS "Element"
, (SELECT cet.TextID "ID"
, cet.Value "Value"
, cet.Link "Link"
, cet.Target "Target"
, cet.Meta "Meta"
, cet.FontColor "FontColor"
, cet.FontFamily "FontFamily"
, cet.FontSize "FontSize"
FROM dbo.vwCampaignElementText cet
WHERE cet.CampaignID = ce.CampaignId
AND cet.ElementID = ce.ElementID
FOR XML PATH ('Text')
) AS "Element"
FROM dbo.vwCampaignElements ce
WHERE ce.CampaignID = Campaign.CampaignId
FOR XML PATH ('Element')
) AS "Campaign/Elements"
FROM vwCampaign Campaign
LEFT JOIN dbo.vwCampaignAudio Audio ON Campaign.CampaignId = Audio.CampaignId
LEFT JOIN dbo.vwCampaignVideo Video ON Campaign.CampaignId = Video.CampaignId
WHERE Campaign.CampaignId = 10370
FOR XML PATH ('Campaign'), ROOT ('Campaigns'), ELEMENTS XSINIL
Le XML sort presque parfait maintenant à l'exception Pour le balisage des sous-questions.
<Campaigns xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Campaign>
<Campaign>
<ID>10370</ID>
<CompanyID>C2811EA3-361A-411A-BB4C-816A5D6C12DB</CompanyID>
<Name>Keith01</Name>
...
<Characters><Character><ID>19029FFC-C1C0-4134-B813-93A9FF17C7F6</ID><Name>Jenna</Name> ...
<Elements><Element><Element><ID>D9B2A643-73EC-4D55-BA34-D643113CEDEA</ID><Editable>1</Editable> ...
</Campaign>
</Campaign>
</Campaigns>
Les sous-questions de caractère et d'élément produisent </> au lieu de </>, comment dites-vous, un balisage sûr URL? Je ne veux pas ça.
L'image et le texte des sous-sols produisent et </ &> au lieu de </>. Remarquez qu'il a été rendu en sécurité URL deux fois! Je ne veux pas non plus ça.
Toute idée de la façon d'obtenir le balisage réel au lieu de cela et mince. :)
Tia
La solution
Vous devriez probablement transférer la «campagne» dans le chemin:
SELECT Campaign.CampaignId "ID"
, Campaign.CompanyId "CompanyID"
, Audio.AudioID "Audio/ID"
, Audio.[Name] "Audio/Name"
...
FROM vwCampaign Campaign
LEFT JOIN dbo.vwCampaignAudio Audio
...
WHERE Campaign.CampaignId = 10370
FOR XML PATH('Campaign'), ELEMENTS XSINIL
Mise à jour
Pour le problème des sucheries, vous devez utiliser le FOR XML PATH(..),
TYPE
Pour créer une valeur XML tapée (par opposition à une chaîne contenant du XML). Une sous-requête typée XML créera un élément XML, une chaîne insérera simplement le résultat sous forme de texte () et sera échappée.
select a, (select b from t for xml path("b"), type) as "*"
from ... for xml path("a")