使用变量SQL获取特定的xml子节点

时间:2014-09-22 15:13:06

标签: sql xml xquery

我需要在一段时间内获取我的xml中的子节点的特定值。 我有一个带有各种'DangerAlrt'标签的xml,我需要获得'Title'和'Message'值,而index有一个特定值。

我的意思是。这是我的xml

Declare @myxml xml ='<Shipment>
                  <InfoAlerts>
                    <InfoAlert>
                      <Title>Workflow Instance Id</Title>
                      <Message>59c541de-b8c6-4e5a-884f-14a68816763c</Message>
                    </InfoAlert>
                  </InfoAlerts>
                  <SuccessAlerts>
                    <SuccessAlert>
                      <Title>Schema Validation</Title>
                      <Message>Ok</Message>
                    </SuccessAlert>
                  </SuccessAlerts>
                  <WarningAlerts />
                  <DangerAlerts>
                    <DangerAlert>
                      <Title>Valid City Name</Title>
                      <Message>Error</Message>
                    </DangerAlert>
                    <DangerAlert>
                      <Title>Valid something</Title>
                      <Message>Error2</Message>
                    </DangerAlert>
                  </DangerAlerts>
                 </Shipment>'

如果我需要特定节点:

select @myxml.query('data(//DangerAlert/Message)')

很好,但这会让我回复'DangerAlert'中'消息'的所有值。

现在,我可以使用以下命令返回'Message'的特定值:

select @myxml.query('data(//DangerAlert/Message)[1]') -- show me:  Error

select @myxml.query('data(//DangerAlert/Message)[2]') -- show me:  Error2

太棒了!但是,当我有很多'DangerAlert'的节点时,我会在一段时间内使用这句话

select @myxml.query('data(//DangerAlert/Message)[local-name() = sql:variable("@i")]') -- where 'i' is the variable (converted to string) used to iterate

但不起作用。什么都没有回复:( 如何将sql变量用作索引值到这个表达式中?

1 个答案:

答案 0 :(得分:0)

data()不是必需的(而且几乎从不)。您正确引用了SQL变量,但local-name()返回元素名称,而不是元素值。

如果您想匹配其子<DangerAlert>与您的变量匹配的<Message>

select @myxml.query('//DangerAlert[Message = sql:variable("@i")]')

更新:在评论中,您已明确表示您只想迭代<Title>值,而不是与DangerAlert / Message值匹配。在这种情况下,简单地返回所有标题会更有效,而不是在SQL中强制迭代。

select @myxml.query('//DangerAlert/Title')

如果迭代器的目的是限制返回的值的数量,那么你可以使用这个XPath在单个查询中更有效地做到这一点:

select @myxml.query('//DangerAlert[fn:number() le sql:variable("@max-results")]/Title')

另请注意,如果您打算返回字符串,请使用string()而不是data()

data(//DangerAlert/Title) =&gt; //DangerAlert/Title/string()