2012-09-20 110 views
0

我试图获得猫的价值,但它回报我空。请帮助我获得这个价值。提前致谢!xquery获取节点值

DECLARE @xml XML 
SET @xml = ' 
<cat:catalog xmlns:cat="http://datypic.com/cat" 
      xmlns:prod="http://datypic.com/prod"> 
    <cat:number>1446</cat:number> 
    <prod:product> 
    <prod:number>563</prod:number> 
    <prod:name prod:language="en">Floppy Sun Hat</prod:name> 
    </prod:product> 
</cat:catalog>' 

Select @xml.value('declare namespace ns="xmlns:cat=http://datypic.com/cat"; /ns:cat[1]/number[1]', 'int') 

回答

2

您试图抓住“猫[1]”,但没有元素“猫”,它只是一个前缀。你想要“目录”我相信。此外,您还必须为“数字”子项添加名称空间。你写的声明命名空间的方式也是我认为不正确的。在那里不需要“xmlns:cat =”。

换句话说:

Select @xml.value('declare namespace ns="http://datypic.com/cat"; /ns:catalog[1]/ns:number[1]', 'int') 

...应该工作。但podiluska的前缀更改更合适,因为“ns”不提供有关正在使用的命名空间的任何提示。要记住的重要一点是前缀是任意的(可以是任何东西),但是你必须将它绑定到你想要的那个名字空间中的任何元素。

+0

感谢您的回复!我想获得cat:数字值。好吧,我用Select @ xml.value('/ catalog [1]/cat [1]','int')替换最后一行,但是stil得到null。 – JohnyMotorhead

+0

是的,这项工作太棒了!感谢你们的帮助! – JohnyMotorhead

2

尝试

Select @xml.value('declare namespace cat="http://datypic.com/cat"; 
    (/cat:catalog/cat:number)[1]','int') 
+0

这就像一个魅力工作!非常感谢你! – JohnyMotorhead

1

你也可以做到这一点使用WITH XMLNAMESPACES,这使得该命名空间声明适用于在整个声明中,而不是单一的调用.value的。如果您需要从XML中获取多个值,这非常有用,例如

DECLARE @xml XML 
SET @xml = '<cat:catalog xmlns:cat="http://datypic.com/cat" xmlns:prod="http://datypic.com/prod"> 
    <cat:number>1446</cat:number> 
    <prod:product> 
    <prod:number>563</prod:number> 
    <prod:name prod:language="en">Floppy Sun Hat</prod:name> 
    </prod:product> 
</cat:catalog>' 

;WITH XMLNAMESPACES (
'http://datypic.com/cat' AS cat, 
'http://datypic.com/prod' AS prod 
) 
SELECT 
    c.c.value('(cat:number/text())[1]', 'INT') 'cat:number', 
    p.c.value('(prod:number/text())[1]', 'INT') 'prod:number', 
    p.c.value('(prod:name/@prod:language)[1]', 'VARCHAR(2)') 'prod:language', 
    p.c.value('(prod:name/text())[1]', 'VARCHAR(50)') 'prod:name' 
FROM @xml.nodes('cat:catalog') c(c) 
    CROSS APPLY c.c.nodes('prod:product') p(c) 
+0

感谢鲍勃!这是一个很好的提示,也许我会用它! – JohnyMotorhead