2016-07-04 5 views
1

У меня есть xml-файл с продуктами. я разделить его в таблицу с одной строкой для каждого продукта с номером продукта и XMLполучить все атрибуты из узлов с тем же именем

SKU | xml 
----|------- 
1111|<product><price>123</price....</product> 
1112|<product><price>345</price....</product> 

Атрибуты хранятся как это:

<attribute-list> 
    <attribute name="tax_id" attribute-type="integer"><value default="1">2</value></attribute> 
     <attribute name="weight" attribute-type="integer"><value default="1">258</value></attribute> 
     <attribute name="length" attribute-type="integer"><value default="1">180</value></attribute> 
     <attribute name="width" attribute-type="integer"><value default="1">115</value></attribute> 
     <attribute name="height" attribute-type="integer"><value default="1">15</value></attribute> 
     <attribute name="series_name" attribute-type="string"><value language-id="DE" default="1"><![CDATA[CSV]]></value></attribute> 
     <attribute name="country_of_origin_code" attribute-type="string"><value default="1">LT</value></attribute> 
     <attribute name="number_of_pages" attribute-type="string"><value default="1">288</value></attribute> 
... 
</attribute-list> 

Различные продукты могут иметь различные атрибуты, например, размер обуви не имеет отношения к книге :-)

Я хотел бы выбрать все возможные имена атрибутов.

attr 
---- 
weight 
length 
number_of_pages 
shoe_size 

я могу получить все возможные значения для атрибута название данного

select distinct xml.value('(/product/attribute-list/attribute[@name="color"])[1]', 
'varchar(100)') as colors from product_xml 

Я получаю близко с

SELECT distinct cast(T2.attr.query('.') as nvarchar(max)) 
FROM product_xml 
CROSS APPLY xml.nodes('/product/attribute-list/attribute') as T2(attr) 

Здесь я получаю запись для каждого возможного attribute- имя и значение

Так что я просто пропустил последний шаг только для получения имени.

EDIT: быстрый и грязный версия здесь:

;with p as (SELECT distinct cast(T2.attr.query('.') as nvarchar(max)) at 
FROM product_xml 
CROSS APPLY xml.nodes('/product/attribute-list/attribute') as T2(attr)) 
select distinct left(at,CHARINDEX('>',at)) from p 

Это производит каждый атрибут в записи сам по себе, что я могу затем манипулировать в приложении (PHP), не так чисто, как только получая имя в одиночку, но легко анализируя и только для использования очень редко.

<attribute name="age_rating" attribute-type="string"> 
<attribute name="aroma" attribute-type="string"> 
<attribute name="barcode" attribute-type="string"> 
<attribute name="barcode_type" attribute-type="string"> 

ответ

1

Это вы что искали? Это утверждение перечисляет все @name атрибуты для каждого атрибута, а затем и захватывает фактическое Value, а также @DefaultValue из <Value> подузла:

SELECT DISTINCT 
    AttrName = XC.value('@name', 'varchar(50)'), 
    DefaultValue=XC.value('(value/@default)[1]', 'varchar(50)'), 
    Value=XC.value('(value)[1]', 'varchar(50)') 
FROM 
    product_xml 
CROSS APPLY 
    xml.nodes('/product/attribute-list/attribute') AS XT(XC) 

Это показывает мне что-то вроде:

enter image description here

+1

Не совсем, поскольку мне просто нужно уникальное e AttrName, мне нужно обработать каждое имя атрибута в приложении: foreach attrname, вставить его в магазин, получить attrname_id, значение foreach этого attrname вставить его в магазин с этим attrname_id. Но ваше предложение заставило меня найти решение, поэтому Я приму это как ответ. –

+0

Кроме того, мне нужно обрабатывать атрибуты вручную, поскольку некоторые из них являются атрибутами в глазу магазина, например shoe_size, которые могут разделять вариации, а некоторые - такие как вес, который клиент не выбирает, а некоторые не быть использованным вообще –

0

Solution основанный на @mark_s

SELECT distinct AttrName = attr.value('@name', 'varchar(50)') 
FROM product_xml 
CROSS APPLY xml.nodes('/product/attribute-list/attribute') as T2(attr) 
Смежные вопросы