将XML键值对转换为字符串

时间:2019-06-04 11:41:52

标签: sql-server xml tsql xquery

我有这个查询:

SELECT 
    XMLColumn.i.query('.') AS XMLColumn, 
    ID
FROM
    MyTable
CROSS APPLY 
    MyTable.XMLColumn.nodes('Root/Fields') AS Col(i)

返回此结果:

╔═════════════════════════╦════╗
║        XMLColumn        ║ ID ║
╠═════════════════════════╬════╣
║ <Fields>                ║  1 ║
║   <Field>               ║    ║
║     <Name>First</Name>  ║    ║
║     <Value>1</Value>    ║    ║
║   </Field>              ║    ║
║   <Field>               ║    ║
║     <Name>Second</Name> ║    ║
║     <Value>2</Value>    ║    ║
║   </Field>              ║    ║
║   <Field>               ║    ║
║     <Name>Third</Name>  ║    ║
║     <Value>3</Value>    ║    ║
║   </Field>              ║    ║
║ </Fields>               ║    ║
╚═════════════════════════╩════╝

是否可以将XML结构转换为以下字符串格式?

╔══════════════════════════╦════╗
║        XMLColumn         ║ ID ║
╠══════════════════════════╬════╣
║ First=1;Second=2;Third=3 ║  1 ║
╚══════════════════════════╩════╝

2 个答案:

答案 0 :(得分:2)

这是一种纯XQuery方法

DECLARE @x XML = 
N'<Fields>
   <Field>
      <Name>First</Name>
      <Value>1</Value>
   </Field>
   <Field>
      <Name>Second</Name>
      <Value>2</Value>
   </Field>
   <Field>
      <Name>Third</Name>
      <Value>3</Value>
   </Field>
</Fields>';

-查询

SELECT STUFF(
@x.query
('
    for $fld in /Fields/Field
    return <x>{concat(";"
                     ,($fld/Name/text())[1]
                     ,"="
                     ,($fld/Value/text())[1])
               }</x>
').value('.','nvarchar(max)'),1,1,'');

简而言之:

我们遍历所有字段并创建这种格式的全新XML

<x>;First=1</x>
<x>;Second=2</x>
<x>;Third=3</x>

.value().一起用作XPath将以字符串形式返回整个内容(不带标签)。 STUFF()用于删除开头的;

答案 1 :(得分:1)

您可以使用.nodes和.value XML data type methods从XML中获取元素值,然后使用SQL Server FOR XML技巧将这些值连接成一个定界的字符串。该代码的结果包含一个尾随定界符-这可能适合或不适合您的需求。

declare @x xml = '<Fields>
   <Field>
      <Name>First</Name>
      <Value>1</Value>
   </Field>
   <Field>
      <Name>Second</Name>
      <Value>2</Value>
   </Field>
   <Field>
      <Name>Third</Name>
      <Value>3</Value>
   </Field>
</Fields>'

-- Use .nodes and .value methods to get the element values as a rowset.
select
    c.value('Name[1]', 'varchar(100)'),
    c.value('Value[1]', 'int')
from
    @x.nodes('/Fields/Field') as T(c)

-- Use the FOR XML trick to concatenate the values.
select c.value('Name[1]', 'varchar(100)') + '=' + c.value('Value[1]', 'varchar(20)') + ';' AS [text()]
from @x.nodes('/Fields/Field') as T(c)
for xml path ('')