get tous les attributes des nœuds du même nom

J'ai un file xml avec des produits. Je l'ai divisé en une table avec une ligne pour chaque produit avec le numéro de produit et xml

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

Les attributes sont stockés comme ceci:

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

Différents produits peuvent avoir des attributes différents, par exemple la taille de la chaussure n'est pas pertinente pour un livre 🙂

Je voudrais sélectionner tous les noms d'attributes possibles.

 attr ---- weight length number_of_pages shoe_size 

Je peux get toutes les valeurs possibles pour un atsortingbut-nom donné

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

Je me rapproche avec

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

Ici, je reçois un logging pour chaque atsortingbut-nom et valeur possible

Donc, je manque juste la dernière étape de seulement get le nom.

EDIT: La version rapide et sale est ici:

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

Cela produit chaque atsortingbut dans un logging par lui-même, que je peux ensuite manipuler dans l'application (php), pas aussi propre que d'get le nom seul, mais facilement analysé, et seulement pour être utilisé très rarement.

 <atsortingbute name="age_rating" atsortingbute-type="ssortingng"> <atsortingbute name="aroma" atsortingbute-type="ssortingng"> <atsortingbute name="barcode" atsortingbute-type="ssortingng"> <atsortingbute name="barcode_type" atsortingbute-type="ssortingng"> 

Est-ce ce que vous cherchez? Cette instruction list tous les attributes @name pour chaque atsortingbut, puis saisit également la Value réelle ainsi que le @DefaultValue du sous- @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/atsortingbute-list/atsortingbute') AS XT(XC) 

Cela me montre quelque chose comme:

entrez la description de l'image ici

Solution basée sur @mark_s

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