TSQL Shred XML - Работа с пространствами имен

Вот ссылка на мой предыдущий вопрос об этом же блоке кода с примером работающего куска

Хорошо, я разработчик C# ASP.NET следующих порядков: Заказы должны взять заданный набор данных, уничтожить XML и вернуть столбцы. Я утверждал, что проще выполнять измельчение на стороне ASP.NET, где у нас уже есть доступ к таким вещам, как десериализаторы и т. Д., И ко всему комплексу известных типов, но нет, говорит босс: "уничтожьте это на сервере, верните набор данных, свяжите набор данных со столбцами вида сетки, так что пока я делаю то, что мне сказали. Это все, чтобы отогнать людей, которые придут и скажут "плохие требования".

Задача под рукой:

Текущий код, который не работает:

И если мы изменим предыдущий пост, чтобы включить пространства имен в элементы XML, мы потеряем функциональность, которая была в предыдущем посте...

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)

Если в моем предыдущем посте было показано, что есть гораздо лучший способ сделать это, то мне действительно нужно пересмотреть и этот вопрос, но в случае неудачи этот стиль кодирования хорош, я, вероятно, могу пойти дальше, как есть.

1 ответ

Решение
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
)
Другие вопросы по тегам