Reputation: 1
I am trying to use the java string function with XSLT 1.0. Specifically the the java String replace function.
But it fails with the null pointer exception. Here's what I tried:
1)--Declare namespace and call the java String class
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:jString="http://www.oracle.com/XSL/Transform/java/java.lang.String">
2)--Created a template to search for tag inputs that have an ampersand:
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, '&')">
<xsl:variable name="str1" select="jString:new($text)"/>
<xsl:value-of select="jString:replace($str1,'&','&')" />
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
3)--Call the template in the specific tags
<Nm>
<xsl:variable name="suppNm">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="Payee/Name" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$suppNm" />
</Nm>
However I keep getting a null pointer exception: Caused by: oracle.xdo.parser.v2.XPathException: Extension function error: Error invoking 'replace':'java.lang.NullPointerException'
Can anyone guide me as to how to make this work?
Thanks
Upvotes: 0
Views: 2073
Reputation: 1
I found the solution through trial and error. So which the replace for ' works well , the same for & does not work. So I used the java String contact function to achieve this:
Here's the final template:
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, '&') or contains($text, '&') ">
<xsl:variable name="str1" select="jString:new(translate($text,'áàâäéèêëíìîïóòôöúùûüç','aaaaeeeeiiiioooouuuuc'))"/>
<xsl:value-of select="(jString:replaceAll(jString:replaceAll($str1,'&',jString:concat('&','amp;')),'&apos;','&amp;apos;'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Upvotes: 0
Reputation: 505
Analysing your XSL code:
string-replace-all
there is lack of closed tag when
, so add </xsl:when>
.contains($text, '&')
I suppose Name
block has value something like sample1 & sample2
. In case of &
which is not followed by # (e.g.  
), the XML parser is implicitly looking for one of the five predefined entity names lt
, gt
, amp
, quot
and apos
, or any manually defined entity name. So in input XML the &
must be escaped as &
.jString:replace(string, target, replacement)
NullPointerException exists if target or replacement is null (Java.lang.String.replace() Method), so possibly problem is that target was not picked up cause of &
.
Also for replacing you can use jString:replaceAll(string, regex, replacement)
.For XML below:
<?xml version="1.0"?>
<Payee>
<Name>sample1 & sample2</Name>
</Payee>
Using similar XSL (e.g. replacing &
with "
):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:jString="http://www.oracle.com/XSL/Transform/java/java.lang.String"
exclude-result-prefixes="jString" version="1.0">
<xsl:output method="xml"/>
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, '&')">
<xsl:variable name="str1" select="jString:new($text)"/>
<xsl:value-of select="jString:replaceAll($str1, '&','"')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<Nm>
<xsl:variable name="suppNm">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="/Payee/Name"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$suppNm" />
</Nm>
</xsl:template>
</xsl:stylesheet>
Result is:
<?xml version="1.0" encoding="UTF-8"?>
<Nm>sample1 " sample2</Nm>
Mainly important input XML:
&
as below:<Payee> <Name>Jüërgëns GmbH & S's</Name> </Payee>
Then you should have error: The entity name must immediately follow the '&' in the entity reference.
&
in <![CDATA[]]>
as below:<Payee> <Name><![CDATA[Jüërgëns GmbH & S's]]></Name> </Payee>
Then using XSL as below:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<Nm>
<xsl:value-of select="/Payee/Name" />
</Nm>
</xsl:template>
</xsl:stylesheet>
Output will be as below:
<?xml version="1.0" encoding="UTF-8"?>
<Nm>Jüërgëns GmbH & S's</Nm>
Hope all attentions above will help with your case.
Upvotes: 1