2016-12-01 2 views
2

Я новичок в SQL и XML. Моя цель - получить данные из всех элементов в блоке клиента, но SELECT не возвращает никаких данных. Без пространства имен запрос работает.Выберите данные из XML с помощью пространства имен

Вы можете помочь?

DECLARE @x XML='<BusinessEvent Name="FO.Client"> 
      <ClientMessage xmlns="http://www.fwbs.net/Aderant.BO.Integration/FO.MessageTypes.xsd"> 
       <OriginatingProcessIdentity></OriginatingProcessIdentity> 
       <Operation></Operation> 
       <IsDataIncluded></IsDataIncluded> 
       <Clients> 
        <Client> 
         <GlobalId></GlobalId> 
         <ClID>g</ClID> 
         <No></No> 
         <Type></Type> 
         <Name></Name> 
         <BrCode></BrCode> 
         <Created></Created> 
         <FeeUsrID></FeeUsrID> 
         <DefaultAddID></DefaultAddID> 
         <ContID></ContID> 
        </Client> 
       </Clients> 
      </ClientMessage> 
     </BusinessEvent>' 


    ;WITH XMLNAMESPACES 
     (DEFAULT 'http://www.fwbs.net/Aderant.BO.Integration/FO.MessageTypes.xsd')   
     SELECT TOP 10 cl.c.value('(text())[1]', 'varchar(20)') clid 
    FROM (SELECT @x data) data 
    CROSS APPLY [data].nodes('/BusinessEvent/ClientMessage/Clients/Client/ClID') AS cl(c) 
+0

В @marc_s ответ дал вам помогает вы с пространством имен (хотя ваше решение с 'DEFAULT' было в порядке, если вы ничего не изменили, кроме' .... nodes ('/ *: BusinessEvent ... ', чтобы подстановить пространство имен самого внешнего узла.) Просто один намек: как вы хотите * получить данные из всех элементов в клиентском блоке *, вы должны остановить 'XPath' в' .nodes() 'после клиента, чтобы прочитать каждый элемент с' c.value ('ClID [ 1]», 'NVARCHAR (макс)')'. Это позволяет вам обращаться ко всем внутренним элементам с тем же самым «CROSS APPLY». – Shnugo

ответ

3

Поскольку пространство имен не на корневой элемент, и, таким образом, делает не применяются ко всему документу XML , вы не можете определить его как пространство имен «по умолчанию» в коде T-SQL - вы должны быть конкретными:

;WITH XMLNAMESPACES ('http://www.fwbs.net/Aderant.BO.Integration/FO.MessageTypes.xsd' AS ns)   
SELECT TOP 10 
    cl.c.value('(text())[1]', 'varchar(20)') clid 
FROM 
    @x.nodes('/BusinessEvent/ns:ClientMessage/ns:Clients/ns:Client/ns:ClID') AS cl(c) 

<BusinessEvent> элемент не часть этого XML пространства имен - но если определить его как DEFAULT имен в вашей T-SQL заявление, что пространство имен по умолчанию будет применяться к все ваших элементов XML, как это определено в вашем XPath - поэтому узел <BusinessEvent> верхний уровень НЕ соответствует ....

+0

Хороший улов с пространством имен, +1 с моей стороны. Я думаю, что 'XPath' не следует спускаться до' ns: ClID', но останавливаться после 'ns: Client', чтобы получить доступ к внутренним элементам за один раз (см. Мой комментарий к OP). – Shnugo

Смежные вопросы