A sequence of more than one item is not allowed as the first argument of fn:substring()

169 Views Asked by At

I am getting this error while using substring in xslt, the error message is clear, hence i tried putting the multiple sequence value in variable and using substring for the variable, it doesn't work either, same error. Can someone provide a workaround for this?

Input:

<Path1>
                                    <Path2>SENDER 1</Path2>
                                    <Path2> SENDER xyc</Path2>
                                    <Path2> SENDER </Path2>
                                    <Path2> ORG ID:</Path2>
                                    <Path2> ORG:=</Path2>
                                    <Path2> ORG </Path2>
                                    <Path2> BNF </Path2>
                                    <Path2> BNF NAME:=A</Path2>
                                    <Path2> BNF ADDRESS</Path2>
                                    <Path2> BNF FI ID:=</Path2>
                                    <Path2> BNF FI:=</Path2>
                                    <Path2> REC FI:=</Path2>
                                    <Path2> REC ID:=</Path2>
                                    <Path2> OBI:=</Path2>
                                </Path1>

xslt:

<xsl:element name="EB">

                                            <xsl:element name="ID">
                                                <xsl:value-of select="substring(*:Path1/*:Path2,1,500)"/>
                                            </xsl:element>
                                </xsl:element>
3

There are 3 best solutions below

1
Martin Honnen On BEST ANSWER

You need to select a single Path2, not a sequence, so either make sure you use a positional predicate e.g. Path2[1] or make sure you use the substring in the context of a single Path2 by e.g. matching on Path2.

As for your comment, that sounds as if you want e.g. string-join(Path2) => substring(1, 500) in XPath 3.1 or substring(string-join(Path2, ''), 1, 500) in XPath 2.

0
SimmeD On

The error occurs because there are multiple Path2 elements and you are trying to apply substring function directly on them which returns multiple output sequences, as a result, the function fails as it expects a single string not multiple strings.

As a workaround, you can apply substring to each Path2 element individually by iterating over each Path2 element. Here is how you could do it:

    <xsl:element name="EB">
      <xsl:element name="ID">  
        <xsl:for-each select="*:Path1/*:Path2">
           <xsl:value-of select="substring(.,1,500)"/> 
        </xsl:for-each>
      </xsl:element>
    </xsl:element>

In this code, I have used a for-each loop to iterate over each Path2 element, and then applied substring to each of them individually.

Remember to replace * with your appropriate namespace prefix. Also if you are looking to concat those strings instead of having separate values you can use concat or string-join function.

    <xsl:element name="EB">
      <xsl:element name="ID">  
        <xsl:value-of select="string-join(*:Path1/*:Path2, ', ')"/>
      </xsl:element>
    </xsl:element>

This would join all Path2 values with a comma. Then you can apply substring function on the joined string.

1
y.arazim On

I want all the Path2 tags to be concatenated and the use substring to restrict to max value

That could be done simply by:

<xsl:value-of select="substring(string-join(Path1/Path2, ''), 1 , 500)"/>