简体   繁体   English

SQL 使用标签属性查询 XML

[英]SQL Query to XML with tag attributes

There is a table:这里有张桌子:

CREATE TABLE temp
    (ID int, name varchar(50));

INSERT INTO temp
    ([ID], [name])
VALUES
    (1, 'Value 1'),
    (2, 'Value 2');

Need SQL query returning the following result:需要 SQL 查询返回以下结果:

<root>
 <row>
  <param name="first">1</param>
  <param name="second">Value 1</param>
 </row>
 <row>
  <param name="first">2</param>
  <param name="second">Value 2</param>
 </row>
</root>

Estimated Query is:估计查询是:

SELECT
  [ID] as [param/@name['first']],
  [name] as [param/@name['second']]
FROM
  temp
for xml path('row'), root('root')

Please correct Query to make it work.请更正查询以使其正常工作。

XQuery FLWOR expression gives you a full control on the shape of the XML. XQuery FLWOR表达式使您可以完全控制 XML 的形状。 Check it out:一探究竟:

SQL SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT PRIMARY KEY, [name] varchar(50));

INSERT INTO @tbl (id, [name])
VALUES (1, 'Value 1')
    , (2, 'Value 2');
-- DDL and sample data population, end

;WITH rs(xml_data) AS
(
    SELECT * 
    FROM @tbl
    FOR XML PATH('row'), TYPE, ROOT('root')
)
SELECT xml_data.query('<root>
{ 
    for $r in /root/row
    return 
    <row>
        <param name="first">{data($r/id/text())}</param>
        <param name="second">{data($r/name/text())}</param>
    </row>
}
</root>') AS xml_output
FROM rs;

Output Output

<root>
  <row>
    <param name="first">1</param>
    <param name="second">Value 1</param>
  </row>
  <row>
    <param name="first">2</param>
    <param name="second">Value 2</param>
  </row>
</root>

The simplest approach might be this:最简单的方法可能是这样的:

SELECT  'first' as [param/@name]
        ,ID as [param]
        ,''
        ,'second' as [param/@name]
        ,[name] as [param] 
FROM temp t
FOR XML PATH('row'), root('root');

The idea in short:简而言之:

The engine works down the columns and finds引擎在列下工作并找到

  • We have to open a <root>我们必须打开一个<root>
  • We have to open a <row> for each row of the set我们必须为集合的每一行打开一个<row>
  • Okay, the first column is a new element <param> , we have to open it.好的,第一列是一个新元素<param> ,我们必须打开它。
  • Now the value ("first") has to be written as an attribute @name .现在必须将值(“first”)写为属性@name
  • The next value ( ID ) is also living in <param> , which is still open.下一个值 ( ID ) 也存在于<param>中,它仍然是打开的。 Add it as a text() node.将其添加为text()节点。
  • Well the next column is - uhm - empty???那么下一栏是 - 嗯 - 空??? However... First we must close the open <param> ...但是...首先我们必须关闭打开的<param> ...
  • Okay, the next column looks better.好的,下一栏看起来更好。 There is an element <param> ... Okay, the last one is closed, we have to open a new one!有一个元素<param> ...好的,最后一个关闭了,我们要打开一个新的!

  • and so on...等等...

This also works with fragments of paths:这也适用于路径片段:

SELECT  'first' as [param/onemore/@name]
        ,ID as [param/onemore]
        ,'' AS [param]
        ,'second' as [param/onemore/@name]
        ,[name] as [param/onemore] 
FROM temp t
FOR XML PATH('row'), root('root');

The result结果

<root>
  <row>
    <param>
      <onemore name="first">1</onemore>
      <onemore name="second">Value 1</onemore>
    </param>
  </row>
  <row>
    <param>
      <onemore name="first">2</onemore>
      <onemore name="second">Value 2</onemore>
    </param>
  </row>
</root>

In this case we re-open <onemore> , but we stay within the open <param> .在这种情况下,我们重新打开<onemore> ,但我们留在打开的<param>内。

You can achieve this with sub-queries:您可以通过子查询实现此目的:

SELECT  'first' as [param/@name],
        ID as [param],
        (SELECT 'second' as [param/@name], 
                name as [param] 
        FROM temp t1 WHERE t1.ID = t.ID 
        FOR XML PATH(''), TYPE )  
FROM temp t
FOR XML PATH('row'), root('root')

Output: Output:

<root>
  <row>
    <param name="first">1</param>
    <param name="second">Value 1</param>
  </row>
  <row>
    <param name="first">2</param>
    <param name="second">Value 2</param>
  </row>
</root>

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

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