FOR Sql Server中的XML PATH

Kei*_*ows 2 sql-server for-xml

注意:我已经解决了大部分问题,但遇到了麻烦.请仔细阅读.您将看到我添加(注释)部分的位置.TIA.


我有一个相当广泛的连接查询,我想要转储到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
Run Code Online (Sandbox Code Playgroud)

数据的工作方式我有:

  • 1个广告系列
  • 1个音频行 - 与广告系列行相关
  • 1个视频行 - 与广告系列行相关
  • 1-n个字符行 - 与广告系列行相关
  • 1-n个元素行 - 与广告系列行相关
  • 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>
Run Code Online (Sandbox Code Playgroud)

不幸的是我有一些问题.

  1. 根元素仍然在行级别.根元素应该是
  2. 如果我有3个字符和3个元素,我最终会得到9个根元素.从一个根元素到另一个根元素的唯一变化是哪个字符和哪个元素显示.(并将每个元素与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>
Run Code Online (Sandbox Code Playgroud)

我需要改变什么?我是否需要查看创建XML的不同方法,可能是某种嵌套子句?


注意:在玩了很多googling/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
Run Code Online (Sandbox Code Playgroud)

除了子查询的标记之外,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>
Run Code Online (Sandbox Code Playgroud)

Character和Element子查询正在生成< /> 而不是</>,你怎么说,URL安全标记?我不想要这个.

图像和文本子子查询正在生成&< /& 而不是</>.请注意,它已成为URL安全两次!我也不想要这个.

知道如何获得实际的标记而不是这个废话.:)

TIA

Rem*_*anu 7

您应该将"广告系列"转移到路径中:

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
Run Code Online (Sandbox Code Playgroud)

更新

对于suqueries问题,您需要使用它FOR XML PATH(..),TYPE来创建一个类型化的XML值(而不是包含xml的字符串).XML类型的子查询将创建一个XML元素,一个字符串只会将结果作为text()插入并将被转义.

select a, (select b from t for xml path("b"), type) as "*" 
from ... for xml path("a") 
Run Code Online (Sandbox Code Playgroud)