从具有相同名称的节点获取所有属性

时间:2016-07-04 20:03:17

标签: sql-server xml

我有一个带产品的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) 

这里我得到了每个可能的属性名称和值

的记录

所以我只是错过了获取名字的最后一步。

编辑:快速和肮脏的版本在这里:

;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">

2 个答案:

答案 0 :(得分: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 :(得分:0)

基于@mark_s的解决方案

SELECT distinct AttrName = attr.value('@name', 'varchar(50)') 
FROM   product_xml
CROSS APPLY xml.nodes('/product/attribute-list/attribute') as T2(attr)