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:
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)