将XML子节点放在同一元素的多个父节点下

时间:2014-02-21 02:46:22

标签: sql-server xml xslt

我有一个数据库查询,可以在一个种族下抽取多个候选者并将它们放入XML文件中。我遇到的问题是,有些比赛有超过2名候选人。我的XML数据模板一次只能有2个候选人。这是一个选举代码。到目前为止,我有查询设置,所以它至少拉了4个候选人。当然,如果一个种族少于4个候选者,它会省略NULL数据并仍然输出该种族的2个候选者。我现在甚至参加了比赛,我有18个以上的候选人。这变成了一件苦差事。这是我的疑问:

select  rc.[race number] AS RaceNumber,
    max(case when seqnum = 1 then title1 end) as title1,
    max(case when seqnum = 1 then [precinct percent] end) as PrecintPercent,
    max(case when seqnum = 1 then [candidate num] end) as Winner,
    max(case when seqnum = 1 then Votes end) as WinningVotes,
    max(case when seqnum = 1 then party end) as WinningParty,
    max(case when seqnum = 1 then leader end) as Winner1,
    max(case when seqnum = 1 then CAST(winner AS tinyint) end) as WinnerSelected,
    max(case when seqnum = 1 then [leader percent] end) as WinnerPercent,
    max(case when seqnum = 2 then [candidate num] end) as Loser,
    max(case when seqnum = 2 then Votes end) as LosingVotes,
    max(case when seqnum = 2 then party end) as LosingParty,
    max(case when seqnum = 2 then leader2 end) as Loser2,
    max(case when seqnum = 2 then [leader2 percent] end) as LoserPercent,
    max(case when seqnum = 2 then CAST(winner AS tinyint) end) as LoserSelected,
    max(case when seqnum = 3 then [candidate num] end) as Winner3,
    max(case when seqnum = 3 then Votes end) as Winner3Votes,
    max(case when seqnum = 3 then party end) as Winner3Party,
    max(case when seqnum = 3 then [first name]+[last name]end) as Winner3, 
    max(case when seqnum = 3 then CAST(winner AS tinyint) end) as Winner3Selected,
    max(case when seqnum = 4 then [candidate num] end) as Loser4,
    max(case when seqnum = 4 then Votes end) as Loser4Votes,
    max(case when seqnum = 4 then party end) as Loser4Party,
    max(case when seqnum = 4 then [first name]+ [last name]end) as Loser4,
    max(case when seqnum = 4 then CAST(winner AS tinyint) end) as Loser4Selected


from 
(
select  
        r.title1,
        r.[precinct percent],
        rc.[race number],
        rc.[candidate num],
        rc.[Votes],
        rc.[winner],
        c.[party],
        r.[leader],
        r.[leader percent],
        r.[leader2],
        r.[leader2 percent],
        c.[first name],
        c.[last name],


            row_number() over (partition by rc.[race number] order by votes desc) as seqnum
    from    dbo.[RACE CANDIDATES] rc
    inner join dbo.[CANDIDATE] c    on  rc.[candidate num]  = c.[candidate number]
    inner join dbo.[RACE] r
     on rc.[race number] = r.[race number] 

) rc
group by rc.[race number]
FOR XML PATH ('ELECTION'), ROOT('root')

同样,如果有4个,则输出至少4个候选者。这是xml文档的片段:

<root>
  <ELECTION>
    <RaceNumber>101</RaceNumber>
    <title1>President</title1>
    <PrecintPercent>100</PrecintPercent>
    <Winner>5083</Winner>
    <WinningVotes>999877</WinningVotes>
    <WinningParty>D</WinningParty>
    <Winner1>Barack Obama</Winner1>
    <WinnerSelected>1</WinnerSelected>
    <WinnerPercent>53</WinnerPercent>
    <Loser>5077</Loser>
    <LosingVotes>888888</LosingVotes>
    <LosingParty>R</LosingParty>
    <Loser2>Mitt Romney</Loser2>
    <LoserPercent>47</LoserPercent>
    <LoserSelected>0</LoserSelected>
  </ELECTION>
  <ELECTION>
    <RaceNumber>102</RaceNumber>
    <title1>U.S. Congress Dist. 1</title1>
    <PrecintPercent>100</PrecintPercent>
    <Winner>5085</Winner>
    <WinningVotes>216879</WinningVotes>
    <WinningParty>D</WinningParty>
    <Winner1>Bruce Braley</Winner1>
    <WinnerSelected>1</WinnerSelected>
    <WinnerPercent>57</WinnerPercent>
    <Loser>5086</Loser>
    <LosingVotes>159657</LosingVotes>
    <LosingParty>R</LosingParty>
    <Loser2>Ben Lange</Loser2>
    <LoserPercent>42</LoserPercent>
    <LoserSelected>0</LoserSelected>
  </ELECTION>
  <ELECTION>
    <RaceNumber>133</RaceNumber>
    <title1>DesMoines County Board of Supervisors</title1>
    <PrecintPercent>100</PrecintPercent>
    <Winner>5154</Winner>
    <WinningVotes>11629</WinningVotes>
    <WinningParty>D</WinningParty>
    <Winner1>Bob  Beck</Winner1>
    <WinnerSelected>1</WinnerSelected>
    <WinnerPercent>34</WinnerPercent>
    <Loser>5155</Loser>
    <LosingVotes>11323</LosingVotes>
    <LosingParty>D</LosingParty>
    <Loser2>Jim Cary</Loser2>
    <LoserPercent>33</LoserPercent>
    <LoserSelected>1</LoserSelected>
    <Winner3>5156</Winner3>
    <Winner3Votes>7018</Winner3Votes>
    <Winner3Party>R</Winner3Party>
    <Winner3>DarwinBunger</Winner3>
    <Winner3Selected>0</Winner3Selected>
    <Loser4>5157</Loser4>
    <Loser4Votes>4415</Loser4Votes>
    <Loser4Party>R</Loser4Party>
    <Loser4>JamesSeaberg</Loser4>
    <Loser4Selected>0</Loser4Selected>
  </ELECTION>

如果您注意到,133,其中有4名候选人。我要做的是获得133显示前2个候选人,然后创建一个重复的节点,其余的候选人姓名/投票等。

以下是我正在将选举XML数据解析为自动收录器的XSL文件:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<tickerfeed version="2.4">


 <!-- START ELECTION CAROUSEL -->

  <playlist type="flipping_carousel" name="ELECTION2" target="carousel">
    <defaults>
      <outputchannels>
        <active>ABC</active>
        <active>MYNTV</active>
      </outputchannels>
      <gui-color>#CCFF99</gui-color>
    </defaults>

    <xsl:for-each select="root/ELECTION">
      <xsl:element name="element">
        <template>ELECTION_RESULTS</template>

        <xsl:element name="field">
          <xsl:attribute name="name">50</xsl:attribute><xsl:value-of select="title1" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">51</xsl:attribute><xsl:value-of select="PrecinctPercent" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">52</xsl:attribute><xsl:value-of select="WinnerSelected" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">53</xsl:attribute><xsl:value-of select="Winner1" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">54</xsl:attribute><xsl:value-of select="WinnerPercent" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">55</xsl:attribute><xsl:value-of select="WinningVotes" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">56</xsl:attribute><xsl:value-of select="LoserSelected" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">57</xsl:attribute><xsl:value-of select="Loser2" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">58</xsl:attribute><xsl:value-of select="LoserPercent" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">59</xsl:attribute><xsl:value-of select="LosingVotes" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">60</xsl:attribute><xsl:value-of select="WinningParty" />
        </xsl:element>

        <xsl:element name="field">
          <xsl:attribute name="name">61</xsl:attribute><xsl:value-of select="LosingParty" />
        </xsl:element>
      </xsl:element>
    </xsl:for-each>
</playlist>



 <!-- END ELECTION CAROUSEL -->

我想我的问题是,这可以实现吗?

我应该在XSL文件还是SQL查询中执行操作?

我当前的查询是我能够获得多个canadidates输出的唯一方法。我想弄清楚如何复制比赛号码,特别是剩下候选人的RACETITLE,因为我的股票模板一次只能显示2名候选人。

如果有人能告诉我是或否,那将是理想的,但我必须以某种方式弄明白。谢谢大家的帮助。

编辑**

我只是希望有超过2个候选者的比赛分成他们自己的节点,而不是输出到一个单独的节点,所有4个候选信息,如RACE 133,我想要2 -RACE 133节点,第一组具有第一组候选者,第二组具有第二组候选者。假设比赛有4名候选人。我不知道......我到了一个我觉得甚至不可能的地步。

我真的想弄清楚我是否应该更多地关注查询或尝试使用更复杂的XSL文件获得所需的输出。把头发拉出来。

1 个答案:

答案 0 :(得分:0)

我在评论中得到的是,如果不是使用您的真实数据而是创建一个包含最少行且只有几个字段的样本集,那么它将更容易使用。完全远离候选人和选举,只使用一些显示相同场景的虚拟数据。

我会尝试提供一些建议,因为我相信我理解你的要求。

  

我想我的问题是,这可以实现吗?

是的,我认为可以。

  

我应该在XSL文件或SQL查询中执行操作吗?

我认为你可以这样做,但是今晚我的XSL还不够强大,不知道怎么做。

因此,专注于SQL,我认为您可以将查询拆分为两个,然后在执行FOR XML之前将结果联合起来。这样四边形将在击中XML之前被拆分成对。获取第一部分的seqnums 1和2,第二部分获得3和4。

你借用pagination技术来获取成对的seqnums

什么版本的MSSQL,顺便说一下?