简体   繁体   English

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

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

I have an XML structure like the following我有一个 XML 结构,如下所示

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

Which I have to pull out of a table like...我必须从桌子上拉出来......

Person

Name, Age, Height姓名、年龄、身高

I'm trying to use the FOR XML path stuff in SQL 2005 with a query like我正在尝试在 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')

But it gives me an error about the 'description xsi' namespace being missing.但它给了我一个关于缺少“description xsi”命名空间的错误。 Is there any way to achieve this using FOR XML PATH.有没有办法使用 FOR XML PATH 来实现这一点。 The actual query is rather more complex than this example and would take a lot of effort to change.实际的查询比这个例子要复杂得多,而且要花很多力气去改变。

Thanks谢谢

FOR XML PATH is a little difficult at times (at least from what I know). FOR XML PATH 有时有点困难(至少据我所知)。 This may get you there:这可能会让你到达那里:

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')

Produces:产生:

<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>

A good solution, similar to eddiegroves' but without requiring to reorder the same-name siblings can be found here .一个很好的解决方案,类似于 eddiegroves,但不需要重新排序同名兄弟姐妹,可以在这里找到。

An adapted code sample (also modified from eddiegroves' answer):改编的代码示例(也从 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('')

I don't think it's possible to deal with sibling nodes with the same name using FOR XML PATH .我认为使用FOR XML PATH处理同名的兄弟节点是不可能的。

I was able to generate your schema using FOR XML EXPLICIT .我能够使用FOR XML EXPLICIT生成您的架构。

The output isn't valid XML as is doesn't include a definition for then xsi namespace, but it does match your spec: 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> 

--after tag printed I added the following field to my query to get tag to close & open --打印标签后,我在查询中添加了以下字段以关闭和打开标签

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

--used borrowed code --使用借来的代码

We needed to produce something like this...我们需要制作这样的东西......

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

It has repeating E elements.它具有重复的 E 元素。

We did it with the t-sql below.我们用下面的 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 

It should be possible to poke in the xsi attributes as well...应该也可以插入 xsi 属性...

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

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