0

I have a table containing rows of xml in the following format:

<msit:message xmlns:wsa="http://URL1" xmlns:msit="http://URL2" xmlns:env="http://URL3">
  <env:Body>
    <ns0:parent xmlns:ns0="http://URL4">
      <ns0:child>123456789</ns0:child>
...
    </ns0:parent>
  </env:Body>
</msit:message>`

in a table name mytable, column name data.

I have written the following query:

;with xmlnamespaces('http://URL2' as msit, 
                   'http://URL3' as env, 
                   'http://URL1' as wsa,
                   'http://URL4' as ns0)
select
t2.field.value('child[1]','varchar(20)') as ban
from mytable
cross apply data.nodes('/message/Body/parent') t2(field)

it returns empty set, when I need to return 123456789

What am I doing wrong ?

Thank you

2 Answers 2

3

you may need to include the prefixes in the xpath expressions:

declare @mytable table (data xml)
insert into @mytable values
('<msit:message xmlns:wsa="http://URL1" xmlns:msit="http://URL2" xmlns:env="http://URL3">
  <env:Body>
    <ns0:parent xmlns:ns0="http://URL4">
      <ns0:child>123456789</ns0:child>
    </ns0:parent>
  </env:Body>
</msit:message>')

;with xmlnamespaces('http://URL2' as msit, 
                   'http://URL3' as env, 
                   'http://URL1' as wsa,
                   'http://URL4' as ns0)
select
t2.field.value('ns0:child[1]','varchar(20)') as ban
from @mytable
cross apply data.nodes('/msit:message/env:Body/ns0:parent') t2(field)
Sign up to request clarification or add additional context in comments.

Comments

1

The whole point of namespaces is to differentiate between elements that were brought together from multiple documents. It is similar to the way we qualify columns with tables' names or aliases, e.g. t1.x Vs. t2.x. So when you refer to an element you should qualify it with the right namespace.

You might also want to use outer apply instead of cross apply in case there's a missing element.

create table mytable (x xml);
insert into mytable (x) values
(
'       
<msit:message xmlns:wsa="http://URL1" xmlns:msit="http://URL2" xmlns:env="http://URL3">
  <env:Body>
    <ns0:parent xmlns:ns0="http://URL4">
      <ns0:child>123456789</ns0:child>
    </ns0:parent>
  </env:Body>
</msit:message>
'
)
;

;
with        xmlnamespaces
            (
                'http://URL2' as msit
               ,'http://URL3' as env 
               ,'http://URL1' as wsa
               ,'http://URL4' as ns0
            )

select      t2.field.value('ns0:child[1]','varchar(20)') as ban

from                    mytable

            outer apply x.nodes('/msit:message/env:Body/ns0:parent') t2(field)
;

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.