user1201168
user1201168

Reputation: 415

XSLT + XML not forming html in web client app, throwing "no protocol" error

follow-on question to where to put XSLT in client webapp question...

My web service contains this method

@WebMethod public String sayHello()
{
    logger.debug("entering");

    String result = null;

    DateTime currTime = new DateTime();  // now

    result = "greetings from the web service! time is " + DATE_PATTERN.print( currTime);

    logger.debug("exiting ");
    return result;
}

which when called by localhost:8080/myWebService/sayHello returns

<soap:Envelope>
  <soap:Body>
    <ns2:sayHelloResponse>
      <return>greetings from the web service! time is 2015-09-10T22:25:05.281</return>
    </ns2:sayHelloResponse>
  </soap:Body>
</soap:Envelope>

I've crafted a companion spring/hibernate webapp (client) to exercise this web service using this as a pattern

my client webapp contains WEB-INF/xslt/XSLTview.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
    <html>
      <body>
        <div align="center">
          <xsl:apply-templates />
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="/sayHello">
     Welcome from the web service where the time is:
     <xsl:value-of select="return" />
  </xsl:template>

</xsl:stylesheet>

and a controller containing

@RequestMapping(value="viewXSLT")
public ModelAndView viewXSLT(HttpServletRequest request,
                             HttpServletResponse response)
throws IOException
{
    String xmlSource = formsWebServicePortProxy.sayHello();

    Source source = new StreamSource( xmlSource);

    // adds the XML source file to the model so the XsltView can detect
    ModelAndView model = new ModelAndView("XSLTView");
    model.addObject("xmlSource", source);

    return model;
}

and my servlet-context.xml contains

<bean id="xsltViewResolver"  class="org.springframework.web.servlet.view.xslt.XsltViewResolver">
  <property name="order" value="1"/>
  <property name="sourceKey" value="xmlSource"/>
  <property name="viewClass" value="org.springframework.web.servlet.view.xslt.XsltView"/>
  <property name="prefix" value="/WEB-INF/xsl/" />
  <property name="suffix" value=".xsl" />
</bean>

the results of all this is localhost:8080/myWebClient/viewXSLT returns

javax.xml.transform.TransformerException:
    com.sun.org.apache.xml.internal.utils.WrappedRuntimeException:
       no protocol: 
          greetings from the web service! time is 2015-09-10T22:49:24.500

so the method on the service is getting called but something's not right in my controller method. What should I be doing to get the xslt to format the xml coming from the service' method to produce a html page?

TIA,

Still-learning Steve

Upvotes: 2

Views: 1053

Answers (1)

Abel
Abel

Reputation: 57169

In the deleted answer, wero wrote that your problem may be in the new StreamSource(string), which requires a URI. In the comments you wrote:

No, xmlSource does in fact contain the whole XML soap message, which is probably why your suggestion fails with a "Content is not allowed in prolog" errmsg

The fact that xmlSource contains the whole XML soap message shows that at the very least, the constructor call to new StreamSource(xmlSource) is incorrect, because a string containing XML is not the same as a string containing a URI.

You applied his suggestion:

Source source = new StreamSource(new java.io.StringReader(xmlSource));

which gave you a content not allowed in prolog error. This is positive, because this means that now at least your code is trying to parse it as XML.

Usually this later error is due to a wrong encoding, which can be due to the addObject method not getting the right method. You don't seem to say what type xmlSource in the Model has. But if you followed the example from the link you posted, you have something similar to this:

@RequestMapping(value="/viewXSLT")
public ModelAndView viewXSLT(HttpServletRequest request,
        HttpServletResponse response) throws IOException {
    // builds absolute path of the XML file
    String xmlFile = "resources/citizens.xml";
    String contextPath = request.getServletContext().getRealPath("");
    String xmlFilePath = contextPath + File.separator + xmlFile;

    Source source = new StreamSource(new File(xmlFilePath));

    // adds the XML source file to the model so the XsltView can detect
    ModelAndView model = new ModelAndView("XSLTView");
    model.addObject("xmlSource", source);

    return model;
}

Which in turn suggests that the object expected must be of StreamSource type. So we have that part correct. Since you get the prolog error, this can mean one of a few things in the XML world:

  • The string is not properly encoded, for instance, it is seen in the system's default encoding ISO-8859-1 while it actually is UTF-8 with a BOM, or the other way around
  • There is something else than a BOM as the first character prior to the prolog (which is <?xml ...), you can check this easily by saving the streamsource by hand to a file
  • It is not XML at all, again this can be checked by saving it to a file

You can doublecheck this by, after saving the XML locally, to take your XSLT and apply it offline to the XML file.

It is not uncommon to get the encoding wrong. Often, the default can be some ISO-8859-1 encoding when saving a file, while the prolog itself uses UTF-8 encoding. This may point you in the direction of encoding issues.

Upvotes: 2

Related Questions