1

我从 sql server 2008 创建了 xml。我当前的 xml 是使用“FOR XML AUTO”生成的

<Customer Name="john" City="Mumbai">
  <Project Project_Name="pqr" />
</Customer>
<Customer Name="Rocky" City="Delhi">
  <Project Project_Name="abc" />
  <Project Project_Name="lmn" />
</Customer>

但我想要像这样的输出

<Customer >
   <name>John</name>
   <city>Mumbai</city>  
   <Projects>
      <project>
         <Project_Name>pqr</Project_Name>
      </project>
   </Projects>
</Customer>
<Customer >
   <name>Rocky</name>
   <city>Delhi</city>  
   <Projects>
      <project>
         <Project_Name>abc</Project_Name>
        <Project_Name>lmn</Project_Name>
      </project>
   </Projects>
</Customer>

所以基本上我想将父元素的属性转换为子元素。并且想要额外的自定义元素。请帮我。

提前致谢。

4

3 回答 3

3

You need to look at the FOR XML PATH option that SQL Server 2005 introduced - see the What's New in FOR XML in Microsoft SQL Server 2005 document for more information.

Basically, with FOR XML PATH, you can define the shape of your XML very easily. You can define certain structures, you can define certain columns to be output as attributes, and others as elements - totally under your control.

Not knowing your table structure, I can only guess what the tables and columns are called in your case - but you could probably write something like:

SELECT 
    c.ID AS '@ID',   -- define output as attribute on node
    c.Name,  -- if you don't specify anything -> output as element of the same name
    c.City,
    (SELECT
         p.Name as 'Project_Name',   -- define different XML element name for column
         p.DueDate
     FROM 
         dbo.Project p
     WHERE
         p.CustomerID = c.ID
     FOR XML PATH('Project'), TYPE
    ) AS 'Projects'
FROM
    dbo.Customer c
FOR XML PATH('Customer'), ROOT('AllCustomers')
于 2012-04-30T04:57:06.237 回答
0

这是更详细的FOR XML EXPLICIT类型

CREATE TABLE #Customers (
            ID              INT
            , Name          VARCHAR(100)
            , City          VARCHAR(100)
            )
CREATE TABLE #Projects (
            ID              INT
            , Name          VARCHAR(100)
            , Customer_ID   INT
            )

INSERT      #Customers
SELECT      1, 'john', 'Mumbai' UNION ALL
SELECT      2, 'Rocky', 'Delhi' UNION ALL
SELECT      3, 'Stan', 'New York' --UNION ALL

INSERT      #Projects
SELECT      1, 'pqr', 1 UNION ALL
SELECT      2, 'abc', 2 UNION ALL
SELECT      3, 'lmn', 2

SELECT      h.Tag
            , h.Parent
            , NULL          AS [Customer!1]
            , c.Name        AS [Name!1000]
            , c.City        AS [City!2000]
            , NULL          AS [Projects!3000]
            , NULL          AS [Project!3100]
            , p.Name        AS [Project_Name!3110]
FROM        (
            SELECT      NULL, 1 UNION ALL
            SELECT          1, 1000 UNION ALL
            SELECT          1, 2000 UNION ALL
            SELECT          1, 3000 UNION ALL
            SELECT              3000, 3100 UNION ALL
            SELECT                  3100, 3110 --UNION ALL
            ) h(Parent, Tag)
LEFT JOIN   (
            SELECT      1                   AS FirstTag
                        , 3000              AS LastTag
                        , c.*
            FROM        #Customers c
            ) c
ON          h.Tag BETWEEN c.FirstTag AND c.LastTag
LEFT JOIN   (
            SELECT      3100                AS FirstTag
                        , 3110              AS LastTag
                        , c.Name            AS CustomerName
                        , p.Name
            FROM        #Customers c
            JOIN        #Projects p
            ON          c.ID = p.Customer_ID
            ) p
ON          h.Tag BETWEEN p.FirstTag AND p.LastTag
ORDER BY    COALESCE(p.CustomerName, c.Name), p.Name, h.Tag
FOR XML EXPLICIT

DROP TABLE #Customers, #Projects

产生这个

<Customer>
  <Name>john</Name>
  <City>Mumbai</City>
  <Projects>
    <Project>
      <Project_Name>pqr</Project_Name>
    </Project>
  </Projects>
</Customer>
<Customer>
  <Name>Rocky</Name>
  <City>Delhi</City>
  <Projects>
    <Project>
      <Project_Name>abc</Project_Name>
    </Project>
    <Project>
      <Project_Name>lmn</Project_Name>
    </Project>
  </Projects>
</Customer>
<Customer>
  <Name>Stan</Name>
  <City>New York</City>
  <Projects />
</Customer>

请注意,这与您的原始请求不同:下面Projects有单独Project的 s 包装项目名称。这也适用于 sql2000。

于 2012-04-30T11:11:02.777 回答
0

我已经根据您的 Xml 重建了行集,并使用 FOR XML PATH 您可以根据需要构建您的 Xml(为 marc_s 投票):

DECLARE @x XML = '
<Customer Name="john" City="Mumbai">
  <Project Project_Name="pqr" />
</Customer>
<Customer Name="Rocky" City="Delhi">
  <Project Project_Name="abc" />
  <Project Project_Name="lmn" />
</Customer>
'

SELECT 
    c.Name AS 'name'
    , c.City AS 'city'
    , (SELECT
        p.Project_Name AS 'Project_Name'
    FROM (
    SELECT c.value('../@Name', 'VARCHAR(50)') AS CustomerName
    , c.value('./@Project_Name', 'VARCHAR(50)') AS Project_Name
    FROM @x.nodes('//Project') AS t(c)
    ) p WHERE c.Name = p.CustomerName 
    FOR XML PATH('project'), TYPE) AS 'Projects'
FROM 
(
SELECT c.value('./@Name', 'VARCHAR(50)') AS Name
    , c.value('./@City', 'VARCHAR(50)') AS City
FROM @x.nodes('//Customer') AS t(c)
) c
FOR XML PATH('Customer')
于 2012-04-30T05:22:59.737 回答