如何通过存储在图像字段中的XML连接多个节点值-

时间:2018-08-23 13:41:38

标签: sql sql-server xml xpath

我有XML,它存储在SQL的图像字段中。 我可以使用CAST提取xml,然后使用xpath提取所需的节点。 问题是节点是可重复的,我不知道会有多少个节点,因此我也必须将这些值连接起来。就像最后的添加一样,我还需要拆分替换每个字符中的某些字符...

所以我可以接近我想要做的事情:

SELECT c.ID, REPLACE((CAST(CONVERT(VARCHAR(MAX),CONVERT(VARBINARY(MAX), ISNULL(zd.ValidContent, x.Content))) AS XML).value('(//preamble, //preamblehang)[1]', N'nvarchar(max)')), ' – ','|') FROM docs c INNER JOIN zones zd on c.docid = zd.docid ...

(实际上,还有很多其他实体和case语句,但是为了简单起见,我将其剥离了)

这将导致: Keyword result

但是我从CAST获得的XML实际上是这样的:

....
<Arule>&#160;</Arule>
<preamble>[1]&#160;&#160;Merger &#8211; Large merger &#8211; Approval of merger &#8211; Subject to employment conditions.</preamble>
<preamble>[2]&#160;&#160;Merger &#8211; Large merger &#8211; Effect on competition &#8211; Lessening or preventing competition.</preamble>
<preamble>[3]&#160;&#160;Merger &#8211; Large merger &#8211; Efficiency defence &#8211; Section 12A &#8211; Pro-competitive gains outweighing loss to local consumers and production.</preamble>
<preamble>[4]&#160;&#160;Merger &#8211; Large merger &#8211; Public interest &#8211; Merger effects on employment.</preamble>
<preamble>[5]&#160;&#160;Merger &#8211; Large merger &#8211; Relevant product and geographic markets defined on a broad and narrow basis.</preamble>
<preamble>[6]&#160;&#160;Merger &#8211; Large merger &#8211; Market shares and concentration.</preamble>
<EdSummary>Editor&#8217;s Summary</EdSummary>
...

有多个“前导”节点,我的选择仅返回第一个,然后对字符串进行替换。我需要获取所有节点的字符串,然后进行字符串替换。或先替换再用Concat。

我假设我需要在内部插入For语句的某个地方插入query()语句,但到目前为止没有任何效果。任何帮助都会很棒。

注意:XML中的&#8211;是用管道符号替换的连字符(–)。然后,还需要用竖线字符分隔节点。

1 个答案:

答案 0 :(得分:0)

玩了一段时间之后,我设法得到了想要的东西。现在,我将看到也许可以对此进行修改,以使其成为一个函数,或者在存储过程中,以预构建可用于视图中联接的表。

这是使我获得想要的结果的SQL语句:

Declare @xml xml, @ItemID int

Select @xml = CAST('<xml>' + CONVERT(VARCHAR(MAX),CONVERT(VARBINARY(MAX), z.ValidContent)) + '</xml>' AS XML)
FROM docs c WITH(NOLOCK)
INNER JOIN zone z ON c.ID = z.ID
WHERE c.ItemID = @ItemID

CREATE TABLE #KeywordData (nodes nvarchar(max))

INSERT INTO #KeywordData
select replace (B.x.value('.', N'nvarchar(max)'), ' – ','|')
from @xml.nodes('/xml') as A(x)
outer apply A.x.nodes('./preamble') as B(x)

SELECT SUBSTRING(
(
    SELECT '|' + nodes as 'data()'
    FROM #KeywordData FOR XML PATH('')
), 2, 9999) as keywords

DROP TABLE #KeywordData