Hard to believe, but the items ##3-4 are still missing.
(1) DDL and sample data population, i.e. CREATE table(s) plus INSERT, T-SQL statements.
(2) What you need to do, i.e. logic, and your attempt implementation of it in T-SQL.
(3) Desired output based on the sample data in the #1 above.
(4) Your SQL Server version (SELECT @@version;)
So the guess game continues unabated.
There is still a mess around tokens inside the string. The provided DDL specifies a first token value (do we care about it?), but based on the verbiage explanation it suppose to be a 2nd token: Total Revenue.
declare @li varchar(max) ='Segment Detail'
SQL
DECLARE @xml XML
, @li VARCHAR(MAX) ='Segment Detail'
, @newXfundCode VARCHAR(MAX) ='newXfundCode'
, @separator CHAR(1) = '~';
DECLARE @tmpData TABLE (id INT, xmldata XML);
INSERT INTO @tmpData(id, xmldata) VALUES
(1, N'<PWR_ViewAll>
<dgvViewAll_Vertical>
<Section_x0020_>ZB-P1</Section_x0020_>
<LineItem>B. Riley FBR Inc.</LineItem>
<Revise_x0020_Date>08-21-2020</Revise_x0020_Date>
<GroupKey>Consensus Model~Total Revenue~TRIN~NBM~~1~ZB-P1</GroupKey>
</dgvViewAll_Vertical>
<dgvViewAll_Vertical>
<Section_x0020_>CL</Section_x0020_>
<LineItem>Deutsche Bank</LineItem>
<Revise_x0020_Date>02-28-2020</Revise_x0020_Date>
<GroupKey>Segment Detail~Total Revenue~WOW~NBM~~1~CL</GroupKey>
</dgvViewAll_Vertical>
</PWR_ViewAll>');
SET @xml= (SELECT xmldata FROM @tmpData WHERE ID=1);
;WITH rs AS
(
SELECT col.value('(GroupKey/text())[1]', 'VARCHAR(MAX)') AS [Before]
FROM @xml.nodes('/PWR_ViewAll/dgvViewAll_Vertical') AS tab (col)
--WHERE CHARINDEX(@li, col.value('(GroupKey/text())[1]', 'VARCHAR(MAX)')) > 0
)
SELECT *, REPLACE(TRY_CAST('<root><r>' +
REPLACE([before], @separator, '</r><r>') +
'</r></root>' AS XML).query('<root>
{
for $x in /root/r
let $pos := count(/root/r[. << $x[1]]) + 1
return if ($pos=3 and root/*[position() = 2 and ./text()="Total Revenue"]) then <r>{sql:variable("@newXfundCode")}</r>
else $x
}
</root>').query('
for $i in /root/r
return if ($i is (/root/r[last()])[1]) then string($i)
else concat($i, sql:variable("@separator"))
').value('.', 'NVARCHAR(MAX)'),@separator + SPACE(1), @separator) AS [After]
FROM rs;
Output
Before: Segment Detail~Total Revenue~WOW~NBM~~1~CL
After: Segment Detail~Total Revenue~newXfundCode~NBM~~1~CL