当XML有2个包装器时,无法读取内容

Con*_*eak 3 xml xquery sql-server-2008

当您<data>从XML和节点中删除包装器时,此代码可以正常工作,但是当您添加它时,如下所示,我得到0结果.

  -- Declare XML variable
  DECLARE @data XML;

  -- Element-centered XML
  SET @data =
  N'
  <data xmlns="test.xsd">
    <subdata>
      <customer>
        <id>1</id>
        <name>Allied Industries</name>
      </customer>
      <customer>
        <id>2</id>
        <name>Trades International</name>
      </customer>
    </subdata>
  </data>';

  -- Using the query() method
  SELECT T.customer.query('id').value('.', 'INT') AS customer_id,
         T.customer.query('name').value('.', 'VARCHAR(20)') AS customer_name
  FROM @data.nodes('data/subdata/customer') AS T(customer);
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时工作正常:

  -- Element-centered XML
  SET @data =
  N'
    <subdata>
      <customer>
        <id>1</id>
        <name>Allied Industries</name>
      </customer>
      <customer>
        <id>2</id>
        <name>Trades International</name>
      </customer>
    </subdata>
 ';

  -- Using the query() method
  SELECT T.customer.query('id').value('.', 'INT') AS customer_id,
         T.customer.query('name').value('.', 'VARCHAR(20)') AS customer_name
  FROM @data.nodes('subdata/customer') AS T(customer);
Run Code Online (Sandbox Code Playgroud)

<data>父包装器在那里时,是否有人知道我在第一个例子中没有得到结果的原因或原因?

mar*_*c_s 6

该问题与XML数据周围的"包装器"数量无关.问题是:您的第一个示例在节点上定义了XML命名空间(xmlns="test.xsd")<data>,但您的查询不尊重该命名空间.

您需要将查询更改为以下内容:

-- Using the query() method
;WITH XMLNAMESPACES (DEFAULT 'test.xsd')
SELECT 
    T.customer.query('id').value('.', 'INT') AS customer_id,
    T.customer.query('name').value('.', 'VARCHAR(20)') AS customer_name
FROM 
    @data.nodes('data/subdata/customer') AS T(customer);
Run Code Online (Sandbox Code Playgroud)

然后你会得到结果....

如果没有这个XML命名空间声明,你的查询就可以正常工作 - 两个包装器或更多包装器根本不重要.

  • @ZeeTee:我相信如果你的XML数据前缀为'N',那么它就不喜欢utf-8声明了(因为它现在是一个`NVARCHAR`字符串,因此使用UCS-2 Unicode编码).删除该XML声明行,或删除"N"前缀. (2认同)