繁体   English   中英

SQL Server 2005 “FOR XML PATH” 多个同名标签

[英]SQL Server 2005 “FOR XML PATH” Multiple tags with same name

我有一个 XML 结构,如下所示

<root>
    <person>
        <name>James</name>
        <description xsi:type="me:age">12</description>
        <description xsi:type="me:height>6 foot</description>
...

我必须从桌子上拉出来......

姓名、年龄、身高

我正在尝试在 SQL 2005 中使用 FOR XML 路径内容,例如

SELECT
Name as 'name'
Age as 'description xsi:type="me:age"'
Height as 'description xsi:type="me:height"'
FOR XML PATH('person')

但它给了我一个关于缺少“description xsi”命名空间的错误。 有没有办法使用 FOR XML PATH 来实现这一点。 实际的查询比这个例子要复杂得多,而且要花很多力气去改变。

谢谢

FOR XML PATH 有时有点困难(至少据我所知)。 这可能会让你到达那里:

WITH XMLNAMESPACES('uri' as xsi)    
SELECT    
'me:age'     AS 'description/@xsi:type'    
,age         AS 'description'    
,name        AS 'name'   
,'me:height' AS 'description/@xsi:type'    
,height      AS 'description'    
FROM #test    
FOR XML PATH('person')

产生:

<person xmlns:xsi="uri">
  <description xsi:type="me:age">32</description>
  <name>Alice</name>
  <description xsi:type="me:height">6 Foot</description>
</person>
<person xmlns:xsi="uri">
  <description xsi:type="me:age">24</description>
  <name>Bob</name>
  <description xsi:type="me:height">5 Feet 5 Inches</description>
</person>

一个很好的解决方案,类似于 eddiegroves,但不需要重新排序同名兄弟姐妹,可以在这里找到。

改编的代码示例(也从 eddiegroves 的答案修改):

WITH XMLNAMESPACES('uri' as xsi)
SELECT name AS 'person/name'
,   'me:age' AS 'person/description/@xsi:type'
,   age AS 'person/description'
,   '' AS 'person'
,   'me:height' AS 'person/description/@xsi:type'
,   height AS 'person/description'
,   '' AS 'person'
,   'me:weight' AS 'person/description/@xsi:type'
,   weight AS 'person/description'
FROM #test
FOR XML PATH('')

我认为使用FOR XML PATH处理同名的兄弟节点是不可能的。

我能够使用FOR XML EXPLICIT生成您的架构。

output 是无效的 XML 因为不包括xsi命名空间的定义,但它确实符合您的规范:

create table #test
(id int identity
,name varchar(50)
,age int
,height varchar(20))

insert #test (name,age,height)
select 'Alice',32,'6 feet one inch'
union select 'Bob',30,'5 feet 10 inches'
union select 'Charles',23,'6 feet two inch'

SELECT 1         AS Tag
       ,NULL     AS Parent
       ,''       AS [root!1]
       ,null     AS [person!2!name!ELEMENT]
       ,null     AS [description!3]
       ,null     AS [description!3!xsi:type]  
       ,null     AS [description!4]
       ,null     AS [description!4!xsi:type]     
UNION ALL
SELECT 2         AS Tag
       ,1        AS Parent
       ,null
       ,name
       ,null
       ,null 
       ,null
       ,null    
FROM #test
UNION ALL
SELECT 3         AS Tag
       ,2        AS Parent
       ,null       
       ,name     
       ,age      
       ,'me:age' 
       ,null
       ,null 
FROM #test
UNION ALL
SELECT 4         AS Tag
       ,2        AS Parent
       ,null       
       ,name     
       ,null
       ,null
       ,height   
       ,'me:height'
FROM #test
order by [person!2!name!ELEMENT],Tag
FOR XML EXPLICIT
<rt> 
  <A> 
    <B> 
      <C> 
        <D> 
          <E>a</E> 
          <F>b</F> 
          <G>c</G> 
        </D> 
    <D> 
          <E>x</E> 
          <F>y</F> 
          <G>z</G> 
        </D> 
      </C> 
    </B> 
  </A> 
</rt> 

--打印标签后,我在查询中添加了以下字段以关闭和打开标签

,(SELECT * FROM          
    (SELECT '' AS 'text()'           
    ) l         
    FOR XML PATH(''),type) as 'A/B/C' 

--使用借来的代码

我们需要制作这样的东西......

<rt>
  <A>
    <B>
      <C>
        <D>
          <E>a</E>
          <E>b</E>
          <E>c</E>
          <E>d</E>
        </D>
      </C>
    </B>
  </A>
</rt>

它具有重复的 E 元素。

我们用下面的 t-sql 做到了。

select 
    '' as "A/B/C/D"
    ,
    (
        SELECT * FROM 
        (
              SELECT 'a' AS 'text()'
        UNION SELECT 'b' AS 'text()'
        UNION SELECT 'c' AS 'text()'
        UNION SELECT 'd' AS 'text()'
        ) l
        FOR XML PATH('E'),type 
    ) as 'A/B/C/D'

from [Case]
where [Case].CaseRef = 'YOUR_PKEY' 
for xml path('rt')
go 

应该也可以插入 xsi 属性...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM