1

I receive an XML file from a web service and, and sometimes this XML comes with a namespace, and sometimes it doesn't.

When I have the XML contained in the @myDoc variable, the select returns null. But, if I remove the "xmlns" part, the select returns the value normally.

What am I doing wrong?

DECLARE @myDoc xml
DECLARE @CSTAT VARCHAR(MAX);
SET @myDoc = '<infProt Id="ID311140002329206" xmlns="some_namespace">
    <cStat>100</cStat>
</infProt>'
SET @CSTAT =  @myDoc.value('(/infProt/cStat)[1]', 'VARCHAR(MAX)' )
SELECT @CSTAT
6
  • possible duplicate of Selecting values out of XML with SQL Server 2008 with namespaces Commented Dec 18, 2014 at 12:44
  • Also see msdn.microsoft.com/en-us/library/ms177400.aspx. Commented Dec 18, 2014 at 12:44
  • Patrick, I read the links, but my problem was that, sometimes the namespace came in the XML, and sometimes didn't. When I used the wildcards proposeds by Mikael, it worked! Commented Dec 18, 2014 at 13:05
  • 1
    @abeppler then it is not an issue of your code but a web service's one... you can work around this broken behaviour of the web service learning to handle namespaces inside your sql code but the correct solution is to fix the web service. Commented Dec 18, 2014 at 13:07
  • I agree with you @Paolo, but I just use the web service, I'm not the developer of it... :( Commented Dec 18, 2014 at 13:11

2 Answers 2

4

You need to specify the name space using WITH XMLNAMESPACES, and attribute an alias to the namespace (I've used x here). Note that you'll also need to switch the SET to a SELECT to use this:

WITH XMLNAMESPACES ('some_namespace' as x)
SELECT @CSTAT =  @myDoc.value('(/x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' );

SqlFiddle Demo

Edit, Re : Dynamic with / without namespaces

You can use the namespace agnostic function local-name() to bypass namespaces:

SELECT @CSTAT =  @myDoc.value(
      '(/*[local-name()="infProt"]/*[local-name()="cStat"])[1]', 'VARCHAR(MAX)');

Updated Fiddle

The mandatory caveat when using local-name() is that this will obviously detect an element in any namespace with the same name in the path, unless you also use namespace-uri.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Stuart, and when I had a xml without the namespace? Because I will have the two possibilities. Can I do it dinamically?
Updated, with fiddle.
Or a wildcard. @myDoc.value('(/*:infProt/*:cStat)[1]', 'VARCHAR(MAX)' )
Thanks Mikael! It's exactly what I was looking for!
0

For value() method declare namespace inside select text

DECLARE @myDoc xml
DECLARE @CSTAT VARCHAR(MAX);
SET @myDoc = '<infProt Id="ID311140002329206" xmlns="some_namespace">
    <cStat>100</cStat>
</infProt>'
select  @CSTAT =  @myDoc.value('declare namespace x="some_namespace"; ( /x:infProt/x:cStat)[1]', 'VARCHAR(MAX)' )
select @CSTAT

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.