0

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,'&','&amp;')" /> 
       <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

3
  • 1
    Possible duplicate of What is a NullPointerException, and how do I fix it? Commented Dec 27, 2017 at 14:40
  • & by itself is not legal XML. I’m surprised your XSLT is loaded at all. Commented Dec 27, 2017 at 14:44
  • Calling from XSLT to Java depends entirely on which XSLT processor you are using. I suspect from the error message that it's the Oracle processor, but you need to tell us. Why not switch to XSLT 2.0/3.0 where XPath offers regex-based string replacement natively? Commented Dec 27, 2017 at 17:43

2 Answers 2

1

Analysing your XSL code:

  1. In template string-replace-all there is lack of closed tag when, so add </xsl:when>.
  2. Input XML was not represented, so no one knows what the value inside Payee/Name. Looking at this part contains($text, '&') I suppose Name block has value something like sample1 & sample2. In case of & which is not followed by # (e.g. &#160;), 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 &amp;.
  3. In case when you use 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).
  4. Finally example Using java String functions in xslt:

For XML below:

<?xml version="1.0"?>
<Payee>
    <Name>sample1 &amp; sample2</Name>   
</Payee>

Using similar XSL (e.g. replacing &amp; with &quot;):

<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, '&amp;')"> 
             <xsl:variable name="str1" select="jString:new($text)"/>                 
             <xsl:value-of select="jString:replaceAll($str1, '&amp;','&quot;')" />
          </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> 
  1. Mainly important input XML:

    • If you have it simply text with & 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.

  • If you have & 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 &amp; S's</Nm>

Hope all attentions above will help with your case.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi Thanks very much for your patience in answering my question. I need to escape ampersand with &amp;. But no matter what I try the output comes through as &. Ive tried 1) jString:replaceAll($str1,'&amp;','&amp;amp;') and jString:replaceAll($str1,,'&amp;','&#38;'). Can anyone help me please? This is the alst bit of puzzle I need to figure out. We are using XSLT 1.0
@springblossom can you add your input XML to question?
Hi The input XML is a supplier name, Jüërgëns GmbH & S's I need to replace & with &amp; and ' with &apos;. The replacement of ' with &apos; is working but I havent succeded in replacing & with &amp;. Any help is appreciated.
@springblossom Mainly important how this data parse in input XML, see p.5 I have added to my answer.
Hi, I cant use CDATA as I need to transform two special characters, & and ' at the same time into &amp; and &apos;. I need to show & as &amp; using Java replace All function. Any input is appreciated
0

I found the solution through trial and error. So which the replace for &apos; works well , the same for &amp; 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, '&amp;') or contains($text, '&amp;') ">
               <xsl:variable name="str1" select="jString:new(translate($text,'áàâäéèêëíìîïóòôöúùûüç','aaaaeeeeiiiioooouuuuc'))"/> 
                <xsl:value-of select="(jString:replaceAll(jString:replaceAll($str1,'&amp;',jString:concat('&amp;','amp;')),'&amp;apos;','&amp;amp;apos;'))" />

               </xsl:when>
           <xsl:otherwise>
              <xsl:value-of select="$text" />
           </xsl:otherwise>
           </xsl:choose>

     </xsl:template>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.