OPEN xmlns:dt

问题描述 投票:2回答:3

使用OPENXML在MSSQL 2005中获取dt元素。如何获取xml中的xmlns:dt元素?例如,获得两行的结果集,其中列出了产品ID和国家/地区代码。

121403 GBR

121403美国

declare @xmldata xml
    set @xmldata = 
    '<?xml version="1.0"?>
    <data xmlns="http://www.aaa.com/master_browse_response" xmlns:dt="http://www.aaa.com/DataTypes">
      <products>
        <product>
       <product_id><![CDATA[121403]]></product_id>
          <countries>
            <dt:country>GBR</dt:country>
            <dt:country>USA</dt:country>
          </countries>
        </product>
     </products>
    </data>'

     DECLARE @hDoc int, @rootxmlns varchar(100)
     SET @rootxmlns = '<root xmlns:hm="http://www.aaa.com/master_browse_response"/>'

     EXEC sp_xml_preparedocument @hDoc OUTPUT, @xmldata, @rootxmlns  

     SELECT *
     FROM OPENXML(@hDoc, '//hm:product',2)
     WITH ([hm:product_id] int , [hm:countries] varchar(100))

     --clean up 
     EXEC sp_xml_removedocument @hDoc

这是我通过使用xmlEdgeTable知道的一种解决方案,但是我正在寻找更好的解决方案。

DECLARE @hDoc int, @rootxmlns varchar(100)
SET @rootxmlns = '<root xmlns:hm="http://www.aaa.com/master_browse_response"/>'

EXEC sp_xml_preparedocument @hDoc OUTPUT, @xmldata, @rootxmlns  

CREATE TABLE #xmlEdgeTable
( 
    id int, 
    parentid int,
    localname varchar(20), 
    [text] varchar(20)
)

INSERT INTO #xmlEdgeTable
SELECT id, parentid,localname, cast([text] as varchar(20)) 
FROM OPENXML(@hDoc, '//hm:product',2)

SELECT t6.text, t2.text FROM #xmlEdgeTable AS t1 INNER JOIN 
    #xmlEdgeTable AS t2 ON t1.id = t2.parentid INNER JOIN 
    #xmlEdgeTable AS t3 ON t3.id = t1.parentid INNER JOIN 
    #xmlEdgeTable AS t4 ON t4.id = t3.parentid INNER JOIN 
    #xmlEdgeTable AS t5 ON t4.id = t5.parentid INNER JOIN
    #xmlEdgeTable AS t6 ON t5.id = t6.parentid 
WHERE t1.localname = 'country' and t5.localname ='product_id'

--clean up 
EXEC sp_xml_removedocument @hDoc
DROP TABLE #xmlEdgeTable
sql sql-server sql-server-2005 tsql openxml
3个回答
7
投票

是否有特定的原因需要使用OPENXML来执行此操作?您可以像这样在2005年使用XQUERY轻松获取信息:

declare @xmldata xml    
set @xmldata = 
'<data xmlns="http://www.aaa.com/master_browse_response" xmlns:dt="http://www.aaa.com/DataTypes">
  <products>
    <product>
      <product_id>121403</product_id>
      <countries>
        <dt:country>GBR</dt:country>
        <dt:country>USA</dt:country>
      </countries>
    </product>
  </products>
</data>'

;WITH XMLNAMESPACES 
(
    DEFAULT 'http://www.aaa.com/master_browse_response',
    'http://www.aaa.com/DataTypes' as dt
)
SELECT  x.c.value('(../../product_id)[1]', 'varchar(100)') as product_id,
        x.c.value('(.)[1]', 'varchar(100)') as country
FROM @xmldata.nodes('/data/products/product/countries/dt:country') x(c)

较新的XQUERY功能是解决问题的更好选择。

编辑:OPENXML的相同解决方案是:

declare @xmldata xml    
set @xmldata = 
'<data xmlns="http://www.aaa.com/master_browse_response" xmlns:dt="http://www.aaa.com/DataTypes">
  <products>
    <product>
      <product_id>121403</product_id>
      <countries>
        <dt:country>GBR</dt:country>
        <dt:country>USA</dt:country>
      </countries>
    </product>
  </products>
</data>'

DECLARE @hDoc int, @rootxmlns varchar(100)
SET @rootxmlns = '<root xmlns:hm="http://www.aaa.com/master_browse_response" xmlns:dt="http://www.aaa.com/DataTypes"/>'
EXEC sp_xml_preparedocument @hDoc OUTPUT, @xmldata, @rootxmlns

SELECT *
FROM OPENXML(@hDoc, '//hm:product/hm:countries/dt:country',2)
        WITH(Country    varchar(100) '.',
             Product_ID varchar(100) '../../hm:product_id')

EXEC sp_xml_removedocument @hDoc

2
投票

对于较小的数据集,XQuery和OPENXML之间没有太大区别

这里是解析6.5 MB xml文件以获得27,615行的结果:

  1. 带有dt的OPENXML:2秒
  2. 带有#xmlEdgeTable的OPENXML:6分38秒
  3. XQuery:24分54秒

0
投票

您能帮我这个忙吗?>

<ns2:object xmlns="http://eh.acti" xmlns:ns2="generic">
    <baseTransactionA>
    <branchKey>8999</branchKey>
    <channel>Web</channel>
    <userId>00260234</userId>
  </baseTransactionA>
</ns2:object>

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML , '<root  xmlns:object="http://eh.actimize.com" xmlns:ns2="generic"/>'


SELECT branchKey, channel ,userId
FROM OPENXML(@hDoc, 'ns2:object/baseTransactionA')
WITH 
(
branchKey [varchar](100) 'branchKey',
channel [varchar](100) 'channel',
userId [varchar](100) 'userId'

)
EXEC sp_xml_removedocument @hDoc

我需要如何声明名称空间?

© www.soinside.com 2019 - 2024. All rights reserved.