2009-09-17 4 views
1

Используйте OPENXML для получения элемента dt в MSSQL 2005. Как я могу получить xmlns: dt element в xml? Например, получите набор результатов из двух строк, в которых перечислены идентификатор продукта и код страны.OPENXML с xmlns: dt

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 

ответ

4

Есть ли особая причина, по которой вам необходимо использовать OPENXML? Вы можете легко получить информацию с XQUERY в 2005 году, как это:

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 гораздо лучший выбор для решения вашей проблемы.

EDIT: же решение с 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 
+0

Спасибо! Это спасатель жизни! – Jeremy

2

Для небольшого набора данных, нет большой разницы между XQuery и OPENXML

Ниже приведены результаты для разбора XML-файл 6,5 Мб чтобы получить 27,615 строк:

  1. OPENXML с DT: 2 секунды
  2. OPENXML с #xmlEdgeTable: 6 м inutes 38 секунд
  3. XQuery: 24 минуты 54 секунды
Смежные вопросы