2009-09-04 49 views
1

注:我已經解決了這個問題的大部分,但遇到了一個麻煩。請閱讀底部。您會看到我添加了(注)部分的位置。 TIA。 FOR Sql Server中的XML PATH


我有一個相當廣泛的連接查詢,我想轉儲到XML。我有它幾乎工作,但我錯過了這裏某個地方的概念。我查詢(略)看起來像:

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 

數據的方式工作,我有:

  • 1競選排
  • 1組音頻行 - 相關活動 行
  • 1視頻行 - 與活動有關 行
  • 1-n字符行 - 與 活動行有關
  • 1-正元件行 - 相關 運動行
  • 0或1圖像行 - 與每個 元件行
  • 0或1文本行 - 與每個 元件行

XML出現如下:

<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> 

不幸的是我有這個問題。

  1. 根元素仍然在行級別。根元素應該是
  2. 如果我有3個字符和3個元素,我會以根元素結束。從一個根元素到下一個元素的唯一變化是哪個字符和哪個元素正在顯示。 (並與具有0或1文本和/或圖像中的每個元素的化合物本)

的XML應該出來找類似:

<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> 

我需要做什麼改變嗎?我是否需要看看創建我的XML的另一種方法,可能是某種嵌套子句?


注意: 玩了很多谷歌搜索/ binging後,我改變了我的查詢,所以它使用嵌套查詢。下面是它看起來像現在:

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 

的XML現在出來幾乎是完美的,除了的子查詢的標記。

<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>&lt;Character&gt;&lt;ID&gt;19029FFC-C1C0-4134-B813-93A9FF17C7F6&lt;/ID&gt;&lt;Name&gt;Jenna&lt;/Name&gt; ... 
     <Elements>&lt;Element&gt;&lt;Element&gt;&lt;ID&gt;D9B2A643-73EC-4D55-BA34-D643113CEDEA&lt;/ID&gt;&lt;Editable&gt;1&lt;/Editable&gt; ... 
    </Campaign> 
    </Campaign> 
</Campaigns> 

字符和元素子查詢產生& lt;/& gt;而不是< />,你怎麼說,URL安全標記?我不想要這個。

圖像和文本子查詢產生& amp & lt;/& amp & gt;而不是< />。請注意,它已經使URL安全兩次了!我也不想要這個。

任何想法如何獲得實際的標記而不是這廢話。 :)

TIA

回答

6

你或許應該將 '運動' 轉移到PATH:

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 

更新

對於suqueries問題,您需要使用FOR XML PATH(..),TYPE來創建一個類型化的XML值(而不是一個包含xml的字符串)。一個XML類型的子查詢將創建一個XML元素,一個字符串只會將結果作爲文本()插入並將被轉義。

select a, (select b from t for xml path("b"), type) as "*" 
from ... for xml path("a") 
+1

謝謝。我添加了它以及ROOT屬性(以防我不選擇單個廣告系列)。這解決了我在這一個挑戰中的一個! – 2009-09-04 23:04:02

+0

這是關於我學習FOR XML有一個ROOT選項大聲笑的時間。感謝那。 – 2009-09-04 23:07:31

+0

查看我的帖子中有關子查詢XML問題的更新 – 2009-09-04 23:11:40