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

  • 1
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) –  Dec 27 '17 at 14:40
  • `&` by itself is not legal XML. I’m surprised your XSLT is loaded at all. – VGR Dec 27 '17 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? – Michael Kay Dec 27 '17 at 17:43

2 Answers2

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.

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