3

我在 SQL Server 2005 中有一个简单的表,我希望将其转换为 XML(使用“FOR XML”子句)。我无法让我的 XML 看起来像所需的输出。

我试过浏览网上的各种教程,但我很挣扎。有人可以帮忙吗?

我的桌子看起来像这样

TYPE,GROUP,VALUE
Books,Hardback,56
Books,Softcover,34
CDs,Singles,45
CDS,Multis,78

我需要的输出样式是:

<data>
  <variable name="TYPE">
   <row>
     <column>GROUP</column>
     <column>VALUE</column>
   </row>
   <row>
     <column>GROUP</column>
     <column>VALUE</column>
   </row>
  </variable>
 <variable name="TYPE">
   <row>
     <column>GROUP</column>
     <column>VALUE</column>
   </row>
   <row>
     <column>GROUP</column>
     <column>VALUE</column>
   </row>
  </variable>
</data>

编辑: 据我所知,我需要多个值。我正在生成与 Xcelsius 一起使用的 XML(链接 XML 和 Xcelsius),因此无法控制 XML 的格式。我可以按照链接教程使用 ASP 生成 XML,但我希望直接从 SQL Server 获取它。

编辑2: 我希望有一些优雅和整洁的东西......但Godeke的例子最接近。一些摆弄SQL,我想出了:

select
   "type" as '@name', 
   "group" as 'row/column',
   null as 'row/tmp', 
   "value" as 'row/column'
from tableName
for xml path('variable'), root('data')

几乎按照我想要的方式输出。null/tmp 行甚至不输出;它只是防止串联。仍然标签<variable name="TYPE">为每一行重复,这是我不能拥有的。

4

3 回答 3

2

尽可能接近的是:

select "type" as '@name', "group" as 'row/column1', "value" as 'row/column2'
from tableName
for xml path('variable'), root('data')

将两个项目命名为相同(“column”和“column”)并不是我知道如何一次性完成的事情,但另一方面,这是一个奇怪的 XML 模式选择;如果元素包含不同的数据,通常元素具有唯一的名称。显而易见的选择(将它们都命名为“行/列”)只是将它们在输出中连接成一个值。

另请注意,每个返回的行都将是一个不同于其他行的“变量”元素。要获得没有冗余记录的嵌套将需要一个子查询:

select distinct "type" as '@name'
from Agent
for xml path('variable'), root('data')

是我的第一个想法,但独特的防止嵌套。

所有这一切让我认为要获得所需的确切输出,您可能必须使用 EXPLICIT 模式。也许我的问题是因为我在代码中使用了 DOMDocument :)。

于 2008-10-30T22:59:33.097 回答
1

我更喜欢使用 XML PATH,它提供了一种更好的方式来控制你的元素等。

但这很棘手

 /*
create table #tablename
(
[type] varchar(20),
[group] varchar(20),
[value] varchar(20)
)

insert into #tablename select 'type1','group11','value111'
insert into #tablename select 'type1','group11','value112'
insert into #tablename select 'type1','group12','value121'
insert into #tablename select 'type1','group12','value122'
insert into #tablename select 'type2','group21','value211'
insert into #tablename select 'type2','group21','value212'
insert into #tablename select 'type2','group22','value221'
insert into #tablename select 'type2','group22','value222'

alter table #tablename add id uniqueidentifier

update #tablename set id = newid()
*/

select [type] as '@name',
    (select     
        (select [column] from
            (
                select [group] as 'column', tbn1.type, tbn2.[group]
               from #tablename tbn3 WHERE tbn3.type = tbn1.type and tbn2.[group] =  tbn3.[group]
               union
         select [value], tbn1.type, tbn2.[group]
              from #tablename tbn3 WHERE tbn3.type = tbn1.type and tbn2.[group] = tbn3.[group]
            ) as s
        for xml path(''),type 
        )
    from #tablename tbn2 
    where tbn2.type = tbn1.type
    for xml path('row3'), type
)

from #tableName tbn1 
GROUP BY [type]
for xml path('variable'), root('data') 

给你你想要的我,但优雅和整洁却不是。

于 2008-10-30T22:41:09.297 回答
0

下面的脚本产生所需的格式


<DATA>
    <VARIABLE TYPE="Books">
      <row TYPE="Books">
        <GROUP>精装本</GROUP>
        <VALUE>56</VALUE>
      </row>
      <row TYPE="Books">
        <GROUP>平装</GROUP>
        <VALUE>34</VALUE>
      </row>
    </VARIABLE>
    <VARIABLE TYPE="CDs">
      <row TYPE="CDs">
        <GROUP>单曲</GROUP>
        <VALUE>45< /VALUE>
      </row>
      <row TYPE="CDS">
        <GROUP>Multis</GROUP>
        < VALUE>78</VALUE>
      </row>
    </VARIABLE>
</DATA>

调用


DECLARE @tblItems table (
    [TYPE] varchar(50)
    ,[GROUP] varchar(50)
    ,[VALUE] int
)

DECLARE @tblShredded table (
    [TYPE] varchar(50)
    ,[XmlItem] xml
)

DECLARE @xmlGroupValueTuples xml

insert into @tblItems([TYPE],[GROUP],[VALUE]) values( 'Books','Hardback',56)
insert into @tblItems([TYPE],[GROUP],[VALUE]) values( 'Books','Softcover',34)
insert into @tblItems([TYPE],[GROUP],[VALUE]) values( 'CDs','Singles',45)
insert into @tblItems([TYPE],[GROUP],[VALUE]) values( 'CDS','Multis',78)

SET @xmlGroupValueTuples =
  (
    SELECT
      "@TYPE" = [TYPE]
      ,[GROUP]
      ,[VALUE]
    FROM @tblItems
    FOR XML PATH('row'), root('Root')
  )

INSERT @tblShredded([TYPE], XmlItem)
SELECT
    [TYPE] = XmlItem.value('./row[1]/@TYPE', 'varchar(50)')
    ,XmlItem
FROM dbo.tvfShredGetOneColumnedTableOfXmlItems(@xmlGroupValueTuples)


SELECT
  (
    SELECT
      VARIABLE =
        (
          SELECT
            "@TYPE" = t.[TYPE]

            ,(
              SELECT
                tInner.XmlItem.query('./child::*')
              FROM @tblShredded tInner
              WHERE tInner.[TYPE] = t.[TYPE]
              FOR XML PATH(''), ELEMENTS, type
            )
          FOR XML PATH('VARIABLE'),type
        )
  )
FROM @tblShredded t
GROUP BY
    t.[TYPE]
FOR XML PATH(''), ROOT('DATA')

在哪里


-- Example Inputs
/*
DECLARE @xmlListFormat xml
SET @xmlListFormat =
    '
        <XmlListRoot>
            <Item>004421UB7</Item>
            <Item>59020UH24</Item>
            <Item>542514NA8</Item>
        </XmlListRoot>
    '
*/

-- =============================================
-- Author: 6eorge Jetson
-- Create date: 01/22/3003
-- Description: Shreds an input XML list conforming to the expected list schema
-- =============================================
CREATE FUNCTION [dbo].[tvfShredGetOneColumnedTableOfXmlItems] (@xmlListFormat xml)
RETURNS
@tblResults TABLE (XmlItem xml)
AS
BEGIN

    INSERT @tblResults
    SELECT
        tblShredded.colXmlItem.query('.') as XmlItem
    FROM
        @xmlListFormat.nodes('/child::*/child::*') as tblShredded(colXmlItem)

    RETURN
END
于 2008-10-31T01:40:11.557 回答