简单 xml.nodes t-sql 查询不起作用

Simple xml.nodes t-sql query does not work

福克斯,这里是xml:

declare @xml xml =
Cast('<asset_market_data_response xmlns="http://schemas.bcs.ru/marketing_data_service/in/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <system_block xmlns="http://schemas.bcs.ru/is/clipboard/">
    <originator>Bloomberg</originator>
    <mean_for>IS.Clipboard</mean_for>
    <document_id>e7aa2033-0a53-4390-a09b-504673ea54bb</document_id>
    <event>New</event>
    <event_time>2017-11-23T13:35:49.171696+03:00</event_time>
  </system_block>
  <common_block>
    <request_id>603bc973-39d0-e711-9417-984be16869ec</request_id>
  </common_block>
  <body>
    <date_request>2017-11-22T00:00:00</date_request>
    <data_request_code>bloomberg_bond</data_request_code>
    <data_source_code>Bloomberg</data_source_code>
    <data_version xsi:nil="true" />
    <error_message_source xsi:nil="true" />
    <asset_list>
      <asset>
        <common>
          <identifier>XS0114288789</identifier>
          <trading_floor_code xsi:nil="true" />
          <trading_floor_section_code>Equity</trading_floor_section_code>
          <trading_floor_board_code xsi:nil="true" />
        </common>
        <data_list>
          <data>
            <name>CRNCY</name>
            <value>USD</value>
          </data>
          <data>
            <name>PAR_AMT</name>
            <value>.475000000</value>
          </data>
        </data_list>
      </asset>
      <asset>
        <common>
          <identifier>CH0385518086</identifier>
          <trading_floor_code xsi:nil="true" />
          <trading_floor_section_code>Equity</trading_floor_section_code>
          <trading_floor_board_code xsi:nil="true" />
        </common>
        <data_list>
          <data>
            <name>CRNCY</name>
            <value>CHF</value>
          </data>
          <data>
            <name>PAR_AMT</name>
            <value>5000.000000000</value>
          </data>
        </data_list>
      </asset>
    </asset_list>
  </body>
</asset_market_data_response>' as xml)

下面是小 select 仅用于抓取标识符列:

select c.value('@identifier', 'varchar(50)') as identifier
from @xml.nodes('asset_market_data_response/body/asset_list/asset/common') t(c)

但它没有输出(col name 'identifier' & no rows)。我需要的是:

我的 select 怎么了?太简单了,我不知道哪里出了问题。可能是 xml 本身有问题?

在 xml 本身发现了问题。删除以“/>”结尾的节点 + xml 架构引用:

set @chr =  Replace(
            Replace(
            Replace(
            Replace(
            Replace(
            Replace(
            Replace(@chr, ' xmlns="http://schemas.bcs.ru/marketing_data_service/in/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', ''),
                          ' xmlns="http://schemas.bcs.ru/is/clipboard/"', ''),
                          '<data_version xsi:nil="true" />', ''),
                          '<error_message_source xsi:nil="true" />', ''),
                          '<trading_floor_code xsi:nil="true" />', ''),
                          '<trading_floor_board_code xsi:nil="true" />', ''),
                          '<value xsi:nil="true" />', '<value></value>')

此操作后 xml parce 是:

<asset_market_data_response>
  <system_block>
    <originator>Bloomberg</originator>
    <mean_for>IS.Clipboard</mean_for>
    <document_id>e7aa2033-0a53-4390-a09b-504673ea54bb</document_id>
    <event>New</event>
    <event_time>2017-11-23T13:35:49.171696+03:00</event_time>
  </system_block>
  <common_block>
    <request_id>603bc973-39d0-e711-9417-984be16869ec</request_id>
  </common_block>
  <body>
    <date_request>2017-11-22T00:00:00</date_request>
    <data_request_code>bloomberg_bond</data_request_code>
    <data_source_code>Bloomberg</data_source_code>
    <asset_list>
      <asset>
        <common>
          <identifier>XS0114288789</identifier>
          <trading_floor_section_code>Equity</trading_floor_section_code>
        </common>
        <data_list>
          <data>
            <name>CRNCY</name>
            <value>USD</value>
          </data>
          <data>
            <name>PAR_AMT</name>
            <value>.475000000</value>
          </data>
        </data_list>
      </asset>
      <asset>
        <common>
          <identifier>CH0385518086</identifier>
          <trading_floor_section_code>Equity</trading_floor_section_code>
        </common>
        <data_list>
          <data>
            <name>CRNCY</name>
            <value>CHF</value>
          </data>
          <data>
            <name>PAR_AMT</name>
            <value>5000.000000000</value>
          </data>
        </data_list>
      </asset>
    </asset_list>
  </body>
</asset_market_data_response>

给出期望结果的可操作代码是:

select Tab_ass.Col_ass.value('identifier[1]', 'varchar(50)') as identifier
from @xml.nodes('asset_market_data_response/body/asset_list') as Tab(Col)      
cross apply Tab.Col.nodes('asset/common') Tab_ass(Col_ass)

这也有效:

select t.c.value('identifier[1]', 'varchar(50)') as identifier
from @xml.nodes('asset_market_data_response/body/asset_list/asset/common') t(c)

还有这个:

select t.c.query('./identifier').value('.', 'varchar(50)') as identifier
from @xml.nodes('asset_market_data_response/body/asset_list/asset/common') t(c)

不,你不应该使用字符串方法修复你的XML,这完全没问题!

您只需声明涉及的命名空间:

WITH XMLNAMESPACES(DEFAULT 'http://schemas.bcs.ru/marketing_data_service/in/')
select c.value('(identifier/text())[1]', 'varchar(50)') as identifier
from @xml.nodes('asset_market_data_response/body/asset_list/asset/common') t(c);