简体   繁体   English

使用TSQL解析/查询XML

[英]Parse / query XML using TSQL

I've been fighting this for a while, seems I'm close but not quite there. 我已经打了一段时间,似乎我很接近,但不是那里。 I have a column in a database that looks like this: 我在数据库中有一个列如下所示:

<document>
<items>
<item name="one">one is the first number</item>
<item name="two">two is the second number</item>
</items>
</document>

In this example I need to query and return 'two is the second number'. 在这个例子中,我需要查询并返回'two is the second number'。 I'd also like to do this without creating a temp table. 我也想在不创建临时表的情况下这样做。 Currently I have: 目前我有:

create table #test (item1 xml)
insert into #test (item1) 
values ('<document> <items> <item name="one">one is the first number</item> <item name="two">two is the second number</item> </items> </document>')

select item1.value('(/document/items/item)[2]', 'nvarchar(max)') from #test
select item1.query('/document/items/item[@name="two"]') from #test

The first select returns the correct value but I need to know that it's the 2nd 'index' The second returns what I want but it returns the entire node two.. 第一个选择返回正确的值,但我需要知道它是第二个'索引'第二个返回我想要的但它返回整个节点两个..

What am I missing? 我错过了什么? And, is there a simple way to use the XML without converting to a temp table? 并且,有没有一种简单的方法来使用XML而无需转换为临时表?

I'd also like to do this without creating a temp table 我也想在不创建临时表的情况下这样做

You can use a variable with datatype XML. 您可以使用数据类型为XML的变量。

declare @xml xml

set @xml = 
'<document>
  <items>
    <item name="one">one is the first number</item>
    <item name="two">two is the second number</item>
  </items>
</document>'

select @xml.value('(/document/items/item[@name="two"])[1]', 'nvarchar(max)')

Or you can cast your string to XML in the query. 或者,您可以在查询中将字符串转换为XML。

select cast(
            '<document>
              <items>
                <item name="one">one is the first number</item>
                <item name="two">two is the second number</item>
              </items>
            </document>' as xml
           ).value('(/document/items/item[@name="two"])[1]', 'nvarchar(max)')

Your first query uses .value() which is correct and your second query has the correct XQuery expression. 您的第一个查询使用正确的.value() ,第二个查询具有正确的XQuery表达式。 When using .value() you need to use a XQuery expression that returns a single value. 使用.value()您需要使用返回单个值的XQuery表达式。 This will give you all item nodes where @name is two /document/items/item[@name="two"]) . 这将为您提供所有项目节点,其中@name为2 /document/items/item[@name="two"]) Adding [1] at the end makes sure that you will only get the first occurrence in the XML where @name is two. 最后添加[1]可确保只在@name为2的XML中出现第一个匹配项。

(First off, rather than a temp table, you can use a variable of type xml , as I do below. Such variables can be assigned directly from string literals) (首先,不是临时表,你可以使用xml类型的变量,如下所示。这些变量可以直接从字符串文字中分配)

So I think you mean you want the text value of the item node with name two , in which case you just need to include the appropriate condition in the xpath you use in your value() call: 所以我认为你的意思是你想要name twoitem节点的文本值,在这种情况下你只需要在你在value()调用中使用的xpath中包含适​​当的条件:

DECLARE @x xml

SET @x = '<document> <items> <item name="one">one is the first number</item> 
     <item name="two">two is the second number</item> </items> </document>'

SELECT @x.value('(/document/items/item[@name="two"])[1]', 'nvarchar(max)')

gives

--------------------------------------------------------------
two is the second number

(1 row(s) affected)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM