TSQL解析XML文档

时间:2016-01-30 13:45:12

标签: sql-server xml tsql

我想要在SQL服务器中解析XML。此XML包含与每个游戏相关的游戏列表和规则列表。我希望输出为

        GameID  RuleID  RuleType    IsSelected
        380      16       0          TRUE
        380      19       0          FALSE
        380      17       0          FALSE
        382      16       0          FALSE
        382      19       0          TRUE
        382      17       0          TRUE

我使用下面提到的查询来获取输出,但我的游戏ID会针对与每个游戏相关的规则列表的所有元素重复。

SELECT 
    Game.value('GameID[1]','INT') AS GameID
    ,Game.value('IsSelected[1]','bit') AS GameSelected
    ,Rule1.value('(./RuleID/text())[1]','Int') AS RuleID                             
FROM @x.nodes('GameWorld/GameList/Game') TEMPTABLE(Game) 
OUTER APPLY
Game.nodes('//RuleList/Rule') AS Rules(Rule1)

XML文档如下所述。该文档包含所有游戏的列表,每个游戏都有一个与之关联的规则列表。

<GameWorld xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
  <GameList> 
    <Game> 
      <GameID>380</GameID>  
      <IsSelected>false</IsSelected>  
      <RuleList> 
        <Rule> 
          <RuleID>16</RuleID>  
          <RuleType>0</RuleType>  
          <IsSelected>true</IsSelected> 
        </Rule>  
        <Rule> 
          <RuleID>19</RuleID>  
          <RuleType>0</RuleType>  
          <IsSelected>false</IsSelected> 
        </Rule>  
        <Rule> 
          <RuleID>17</RuleID>  
          <RuleType>0</RuleType>  
          <IsSelected>false</IsSelected> 
        </Rule> 
      </RuleList> 
    </Game>  
    <Game> 
      <GameID>381</GameID>  
      <IsSelected>false</IsSelected>  
      <RuleList> 
        <Rule> 
          <RuleID>16</RuleID>  
          <RuleType>0</RuleType>  
          <IsSelected>true</IsSelected> 
        </Rule>  
        <Rule> 
          <RuleID>19</RuleID>  
          <RuleType>0</RuleType>  
          <IsSelected>false</IsSelected> 
        </Rule>  
        <Rule> 
          <RuleID>17</RuleID>  
          <RuleType>0</RuleType>  
          <IsSelected>false</IsSelected> 
        </Rule> 
      </RuleList> 
    </Game> 
  </GameList> 
</GameWorld>

2 个答案:

答案 0 :(得分:1)

核心问题是因为在您希望XPath / XQuery是相对的上下文中,.之前没有使用//,即Game.nodes('//RuleList/Rule')。请尝试这种方式:

SELECT 
    Game.value('GameID[1]','INT') AS GameID
    ,Rule1.value('RuleID[1]','Int') AS RuleID                             
    ,Rule1.value('RuleType[1]','Int') AS RuleType  
    ,Rule1.value('IsSelected[1]','bit') AS IsSelected
FROM @x.nodes('GameWorld/GameList/Game') TEMPTABLE(Game) 
OUTER APPLY
Game.nodes('./RuleList/Rule') AS Rules(Rule1)

<强> sqlfiddle demo

输出

| GameID | RuleID | RuleType | IsSelected |
|--------|--------|----------|------------|
|    380 |     16 |        0 |       true |
|    380 |     19 |        0 |      false |
|    380 |     17 |        0 |      false |
|    381 |     16 |        0 |       true |
|    381 |     19 |        0 |      false |
|    381 |     17 |        0 |      false |

答案 1 :(得分:0)

SELECT 
    Game.value('GameID[1]','INT') AS GameID,
    Rule1.value('RuleID[1]','Int') AS RuleID,
    Rule1.value('RuleType[1]','Int') AS RuleType,
    Rule1.value('IsSelected[1]','varchar(5)') AS IsSelected
FROM @x.nodes('GameWorld/GameList/Game') TEMPTABLE(Game) 
OUTER APPLY
Game.nodes('//RuleList/Rule') AS Rules(Rule1)