Adee
Adee

Reputation: 67

Update a specific position in a string XSLT

I have an EDI text file which I need to modify using XSLT. I have first transformed the text file into xml which looks like below:

<data>ST^8^347</data>
<data>BAK^00^A^100001396^20240102^^^^20456^a</data>
<data>REF^OQ^5004506</data>

I just need to update the 8th position of the line starting with BAK which is 20456 in above code, to a new value say NEW. Position is determined by delimiter "^"

My xslt code looks like but not working

<data><xsl:value-of select="replace(.,(tokenize(.,'\\^')[9]),'NEW')"/></data>

Expected output is

<data>BAK^00^A^100001396^20240102^^^^NEW^a</data>

Cannot use substring because length of each positions can vary. I can use 8 time substring after but looking for a better approach if possible. Please help.

Upvotes: 1

Views: 181

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

First you need to have a well-formed XML input:

XML

<root>
    <data>ST^8^347</data>
    <data>BAK^00^A^100001396^20240102^^^^20456^a</data>
    <data>REF^OQ^5004506</data>
</root>

Then you can do:

XSLT 3.0

<xsl:stylesheet version="3.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="data[starts-with(., 'BAK^')]"> 
    <xsl:variable name="tokens" select="tokenize(., '\^')" />
    <data> 
        <xsl:value-of select="$tokens[position() lt 9], 'NEW' , $tokens[position() gt 9]" separator="^"/>
    </data> 
</xsl:template> 

</xsl:stylesheet>

to get:

Result

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <data>ST^8^347</data>
   <data>BAK^00^A^100001396^20240102^^^^NEW^a</data>
   <data>REF^OQ^5004506</data>
</root>

Alternatively you could use:

<xsl:value-of select="insert-before(remove($tokens, 9), 9, 'NEW')" separator="^"/>

Or:

<xsl:value-of select="for $i in (1 to count($tokens)) return if ($i=9) then 'NEW' else $tokens[$i]" separator="^"/>

Upvotes: 5

Related Questions