使用SQL Server Replace或CLR Regex替换XML字符串?

时间:2015-03-17 06:47:00

标签: c# sql-server regex clr sql-server-2014

我有以下XML字符串:

<row>
  <id>
    <old></old>
    <new>2151</new>
  </id>
  <name>
    <old></old>
    <new>test</new>
  </name>
  <amount>
    <old></old>
    <new>62</new>
  </amount>
</row>

我需要解析并替换字符串,以便最终结果具有以下格式:

columnname|oldvalue|newvalue^

因此上面的例子看起来像这样:

id||2151^name||test^amount||62^

XML字符串将始终包含一个row节点。其中的节点(ig.id,名称,数量等)将发生变化,其范围可以是几个节点到100多个节点。然而,结构将始终相同。

是否可以直接在SQL Server中执行此操作,还是需要使用CLR函数才能使用正则表达式?

该函数必须是通用的,因为列名将不同。

3 个答案:

答案 0 :(得分:1)

您可以使用local-name()检索节点的名称:

select  col1.value('local-name(.)', 'varchar(max)') + '|' +
        col1.value('(./old)[1]', 'varchar(max)') + '|' +
        col1.value('(./new)[1]', 'varchar(max)') + '^'
from    @x.nodes('/row/*') as tbl(col1)

-->
id||2151^
name||test^
amount||62^

Example at SQL Fiddle.

答案 1 :(得分:0)

如果XML的模式相同且不会改变,那么应该这样做。

string checkStr1 = @"<row>
    <id>
    <old></old>
    <new>2151</new>
    </id>
    <name>
    <old></old>
    <new>test</new>
    </name>
    <amount>
    <old></old>
    <new>62</new>
    </amount>
</row>";
Regex r1 = new Regex(@"\<([a-z]+)\>(?:\t|\r|\n|\s)*\<old\>(.*?)\<\/old\>(?:\t|\r|\n|\s)*\<new\>(.*?)\<\/new\>(?:\t|\r|\n|\s)*</[a-z]+?>");
MessageBox.Show(r1.Replace(checkStr1, m => "^" + m.Groups[1].Value + "|" + m.Groups[2].Value + "|" + m.Groups[3].Value));

最后更换&#34; row&#34;打开和关闭标签......

希望这会有所帮助......

答案 2 :(得分:0)

试试这个,

Declare @xml xml='<row>
  <id>
    <old></old>
    <new>2151</new>
  </id>
  <name>
    <old></old>
    <new>test</new>
  </name>
  <amount>
    <old></old>
    <new>62</new>
  </amount>
</row>'


select 'id||'+  xmlData.Col.value('(./id)[1]', 'varchar(MAX)')+'^' +
'name||'+ xmlData.Col.value('(./name)[1]', 'varchar(MAX)')+'^' +
'amount||'+ xmlData.Col.value('(./amount)[1]', 'varchar(MAX)')+'^'
from  @xml.nodes('//row') xmlData(Col)