更新字符串 XSLT 中的特定位置

Ade*_*dee 1 xml xslt xslt-2.0 xslt-3.0

我有一个 EDI 文本文件,需要使用 XSLT 对其进行修改。我首先将文本文件转换为 xml,如下所示:

<data>ST^8^347</data>
<data>BAK^00^A^100001396^20240102^^^^20456^a</data>
<data>REF^OQ^5004506</data>
Run Code Online (Sandbox Code Playgroud)

我只需要将上面代码中以 BAK 开头的行的第 8 个位置(即 20456)更新为新值(例如 NEW)。位置由分隔符“^”确定

我的 xslt 代码看起来像但不起作用

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

预期输出是

<data>BAK^00^A^100001396^20240102^^^^NEW^a</data>
Run Code Online (Sandbox Code Playgroud)

无法使用子字符串,因为每个位置的长度可能不同。我可以在之后使用 8 次子字符串,但如果可能的话,寻找更好的方法。请帮忙。

mic*_*57k 5

首先,您需要有一个格式良好的 XML 输入:

XML

<root>
    <data>ST^8^347</data>
    <data>BAK^00^A^100001396^20240102^^^^20456^a</data>
    <data>REF^OQ^5004506</data>
</root>
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

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>
Run Code Online (Sandbox Code Playgroud)

要得到:

结果

<?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>
Run Code Online (Sandbox Code Playgroud)

或者你可以使用:

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

或者:

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