简体   繁体   English

如何使用包含不带前缀的命名空间的 sp_xml_preparedocument 在 TSQL 中读取 XML?

[英]How do I read XML in TSQL using sp_xml_preparedocument that includes a namespace without prefix?

I'm running SQL Server 2019 15.0.2095.3 and I want to read the contents of an XML file to then store it into a table.我正在运行 SQL Server 2019 15.0.2095.3,我想读取 XML 文件的内容,然后将其存储到表中。 The problem is that I am not receiving any errors, but the result set is empty when the XML contains a namespace without prefix, but as soon as I remove the prefixless namespace it returns data again (it does work with prefix).问题是我没有收到任何错误,但是当 XML 包含不带前缀的命名空间时结果集为空,但是一旦我删除无前缀命名空间,它就会再次返回数据(它确实使用前缀)。

Here is the code to replicate the problem:这是复制问题的代码:

DECLARE @idoc INT, @doc VARCHAR(1000);   
SET @doc =' 
<ROOT xmlns="http://test.com">  
<Customers>  
   <Orders>  
      <nr>5</nr>
      <line>
        <test>55</test>
        <test2>444</test2>
      </line>
   </Orders>  
</Customers>  
<Customers>  
   <Orders>    
      <nr>4</nr>
      <line>
        <test>44</test>
        <test2>444</test2>
      </line>
   </Orders>  
</Customers>  
</ROOT>';   
  
--Create an internal representation of the XML document.  
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc, '<ROOT xmlns="http://test.com"/>  '
  
-- SELECT statement that uses the OPENXML rowset provider.  
    SELECT *
    FROM       OPENXML (@idoc, '/ROOT/Customers/Orders/nr' ) 

EXEC sp_xml_removedocument @idoc;  

When you remove the namespace <ROOT xmlns="http://test.com"> and just use the element without it as so: <ROOT> it will return a normal result set.当您删除命名空间<ROOT xmlns="http://test.com">并只使用没有它的元素时: <ROOT>它将返回一个正常的结果集。

However I want the query to return the contents without changing the XML但是我希望查询返回内容而不更改 XML

Microsoft proprietary OPENXML() and its companions sp_xml_preparedocument and sp_xml_removedocument are kept just for backward compatibility with the obsolete SQL Server 2000. Their use is diminished just to very few fringe cases.保留 Microsoft 专有的OPENXML()及其伙伴sp_xml_preparedocumentsp_xml_removedocument只是为了与过时的 SQL Server 2000 向后兼容。它们的使用减少到很少的边缘情况。

Starting from SQL Server 2005 onwards, it is strongly recommended to re-write your SQL and switch it to XQuery.从 SQL Server 2005 开始,强烈建议重新编写 SQL 并将其切换到 XQuery。 Also, OPENXML() cannot take advantage of XML indexes while XQuery methods can.此外,OPENXML() 不能利用 XML 索引,而 XQuery 方法可以。

SQL SQL

DECLARE @xml XML;   
SET @xml =
N'<ROOT xmlns="http://test.com">  
<Customers>  
   <Orders>  
      <nr>5</nr>
      <line>
        <test>55</test>
        <test2>444</test2>
      </line>
   </Orders>  
</Customers>  
<Customers>  
   <Orders>    
      <nr>4</nr>
      <line>
        <test>44</test>
        <test2>444</test2>
      </line>
   </Orders>  
</Customers>  
</ROOT>';   

;WITH XMLNAMESPACES(DEFAULT 'http://test.com')
SELECT c.value('(nr/text())[1]', 'INT') AS nr
    , c.value('(line/test/text())[1]', 'INT') AS test
    , c.value('(line/test2/text())[1]', 'INT') AS test2
FROM @xml.nodes('/ROOT/Customers/Orders') AS t(c);

Output输出

+----+------+-------+
| nr | test | test2 |
+----+------+-------+
|  5 |   55 |   444 |
|  4 |   44 |   444 |
+----+------+-------+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM