TSQL XML Shred - Travailler avec des espaces de noms
-
24-10-2019 - |
Question
Voici un lien à ma question précédente sur ce même bloc de code avec un exemple de travail shred
Ok, je suis un C # ASP.NET dev commandes suivantes: Les commandes doivent prendre un ensemble de données, déchiqueter les colonnes XML et retour. Je l'ai soutenu qu'il est plus facile de faire le déchiqueter du côté ASP.NET où nous avons déjà accès à des choses comme désérialiseurs, etc, et l'ensemble du complexe des types connus, mais non, le patron dit « déchiqueter sur le serveur, retourner un ensemble de données, lient l'ensemble de données sur les colonnes du gridview » pour l'instant, je fais ce qu'on m'a dit. Tout cela est à la tête au large des gens qui vont venir le long et dire « mauvaises conditions ».
tâche:
Code actuel qui ne fonctionne pas:
Et si nous modifions le post précédent pour inclure les espaces de noms sur les éléments XML, nous perdons la fonctionnalité que le post précédent a ...
DECLARE @table1 AS TABLE (
ProductID VARCHAR(10)
, Name VARCHAR(20)
, Color VARCHAR(20)
, UserEntered VARCHAR(20)
, XmlField XML
)
INSERT INTO @table1 SELECT '12345','ball','red','john','<sizes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><size xmlns="http://example.com/ns" name="medium"><price>10</price></size><size xmlns="http://example.com/ns" name="large"><price>20</price></size></sizes>'
INSERT INTO @table1 SELECT '12346','ball','blue','adam','<sizes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><size xmlns="http://example.com/ns" name="medium"><price>12</price></size><size xmlns="http://example.com/ns" name="large"><price>25</price></size></sizes>'
INSERT INTO @table1 SELECT '12347','ring','red','john','<sizes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><size xmlns="http://example.com/ns" name="medium"><price>5</price></size><size xmlns="http://example.com/ns" name="large"><price>8</price></size></sizes>'
INSERT INTO @table1 SELECT '12348','ring','blue','adam','<sizes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><size xmlns="http://example.com/ns" name="medium"><price>8</price></size><size xmlns="http://example.com/ns" name="large"><price>10</price></size></sizes>'
INSERT INTO @table1 SELECT '23456','auto','black','ann','<auto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><type xmlns="http://example.com/ns">car</type><wheels xmlns="http://example.com/ns">4</wheels><doors xmlns="http://example.com/ns">4</doors><cylinders xmlns="http://example.com/ns">3</cylinders></auto>'
INSERT INTO @table1 SELECT '23457','auto','black','ann','<auto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><type xmlns="http://example.com/ns">truck</type><wheels xmlns="http://example.com/ns">4</wheels><doors xmlns="http://example.com/ns">2</doors><cylinders xmlns="http://example.com/ns">8</cylinders></auto><auto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><type xmlns="http://example.com/ns">car</type><wheels xmlns="http://example.com/ns">4</wheels><doors xmlns="http://example.com/ns">4</doors><cylinders xmlns="http://example.com/ns">6</cylinders></auto>'
DECLARE @x XML
-- I think I'm supposed to use WITH XMLNAMESPACES(...) here but I don't know how
SELECT @x = (
SELECT
ProductID
, Name
, Color
, UserEntered
, XmlField.query('
for $vehicle in //auto
return <auto
type = "{$vehicle/type}"
wheels = "{$vehicle/wheels}"
doors = "{$vehicle/doors}"
cylinders = "{$vehicle/cylinders}"
/>')
FROM @table1 table1
WHERE Name = 'auto'
FOR XML AUTO
)
SELECT @x
SELECT
ProductID = T.Item.value('../@ProductID', 'varchar(10)')
, Name = T.Item.value('../@Name', 'varchar(20)')
, Color = T.Item.value('../@Color', 'varchar(20)')
, UserEntered = T.Item.value('../@UserEntered', 'varchar(20)')
, VType = T.Item.value('@type' , 'varchar(10)')
, Wheels = T.Item.value('@wheels', 'varchar(2)')
, Doors = T.Item.value('@doors', 'varchar(2)')
, Cylinders = T.Item.value('@cylinders', 'varchar(2)')
FROM @x.nodes('//table1/auto') AS T(Item)
Si mes spectacles post précédents, il y a une bien meilleure façon de le faire, alors je vraiment besoin de revoir cette question aussi, mais sur la chance de ce style de codage est bon, je peux probablement aller de l'avant avec ce que-est .
La solution
DECLARE @x XML;
with xmlnamespaces ('http://www.w3.org/2001/XMLSchema-instance' as xsi
, 'http://www.w3.org/2001/XMLSchema' as xsd
, 'http://example.com/ns' as ns)
SELECT @x = (
SELECT
ProductID
, Name
, Color
, UserEntered
, XmlField.query('
for $vehicle in //auto
return <auto
type = "{$vehicle/ns:type}"
wheels = "{$vehicle/ns:wheels}"
doors = "{$vehicle/ns:doors}"
cylinders = "{$vehicle/ns:cylinders}"
/>')
FROM @table1 table1
WHERE Name = 'auto'
FOR XML AUTO
)