代码之家  ›  专栏  ›  技术社区  ›  jcolebrand

TSQL分解XML-使用名称空间

  •  2
  • jcolebrand  · 技术社区  · 16 年前

    Here's a link to my previous question on this same block of code with a working shred example

    好的,我是一个C#ASP.NET开发人员,遵循以下命令:获取给定的数据集,分解XML并返回列。我认为在ASP.NET端进行分解比较容易,因为我们已经可以访问反序列化程序等,以及已知类型的整个复合体,但是没有,老板说“在服务器上分解它,返回一个数据集,将数据集绑定到gridview的列”,所以现在,我正在做我被告知的事情。这些都是为了阻止那些会说“不好的要求”的人。

    手头的任务:

    如果我们修改了前一篇文章以在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 回复  |  直到 9 年前
        1
  •  4
  •   Remus Rusanu    16 年前
    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
    )
    
    推荐文章