0

I have a program that writes some XML files like this:

Path path = Paths.get(new URI("file://" + this.destination));
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Responses>\n");
// Get a bunch of data from a remote web service
sb.append("</Responses>");
Files.write(path, sb.toString().getBytes(Charset.forName("UTF-8")), StandardOpenOption.CREATE);

The code that reads the files looks like this:

import javax.xml.transform.stream.StreamSource;
// ...
// Load XSLT
Source source = new StreamSource(this.getClass().getClassLoader().getResourceAsStream("my_transform.xsl"));
Transformer transformer = factory.newTransformer(source);
// set parameter
transformer.setParameter("db", dbName);
// Get input file
Source xmlSource = new StreamSource(this.pathToFile.toFile());
// Execute transform
transformer.transform(xmlSource, outputTarget);

The transform itself is very simple:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="no" encoding="utf-8"
        media-type="text/plain" />
    <xsl:strip-space elements="*" />
    <xsl:param name="db" />
    <xsl:template match="/ELEMENT1/ELEMENT2/ELEMENT3/data[@dbname=$db]">
        <xsl:value-of select="../../@id" />
        <xsl:text>&#x9;</xsl:text>
        <xsl:value-of select="./@primary_id" />
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

The XML files are large, but they look OK, here's the first few lines of one:

<?xml version="1.0" encoding="utf-8"?>
<Responses>
<Response id="ID0000123">
  <opt>
    <data  primary_id="ID0000123-01" version="0">

When my code attempts to execute the transform, it throws an exception:

ERROR:  'Content is not allowed in prolog.'
ERROR:  'com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Content is not allowed in prolog.'
javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Content is not allowed in prolog.
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:749)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:351)
...

I'm not sure where this is coming in from. The last time this happened to me it was a character set mismatch, but in this case I'm writing the file as UTF-8 and loading it with StreamSource which I thought would load the character set correctly, so I'm not sure why the transform is failing.

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
  • 1
    The error message is different, but the causes and remedies are the same as is found in the answer to this question: [**Error: The processing instruction target matching “\[xX\]\[mM\]\[lL\]” is not allowed**](http://stackoverflow.com/questions/19889132/error-the-processing-instruction-target-matching-xxmmll-is-not-allowed) – kjhughes Jan 27 '17 at 21:32
  • Possibly related: http://stackoverflow.com/questions/4569123/content-is-not-allowed-in-prolog-saxparserexception – Mick Mnemonic Jan 27 '17 at 23:05
  • Possible duplicate of [Error: The processing instruction target matching "\[xX\]\[mM\]\[lL\]" is not allowed](http://stackoverflow.com/questions/19889132/error-the-processing-instruction-target-matching-xxmmll-is-not-allowed) – Mathias Müller Jan 28 '17 at 08:46

3 Answers3

2

The actual solution had nothing to do with the XML file. The library that I was using had a bug as was returning the path to a directory instead of a valid XML file. I tried to delete this question but because it's been answered, I can't. I sure feel silly now...

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
1

This error usually happens when there are some characters before the XML header: Check specially for blank characters (because they are difficult to see at a glance) at the beginning of the XML source files.

Little Santi
  • 8,563
  • 2
  • 18
  • 46
  • 1
    An interesting idea. I suggest to also check for UniCode [BOM](https://en.wikipedia.org/wiki/Byte_order_mark)s at the start of the file. – zx485 Jan 27 '17 at 22:11
  • @zx485 Yes, well said. An hexadecimal editor could be useful for that. If that is the case, a way to fix it could be to specify the proper **encoding** when reading the source XML: `Source xmlSource = new StreamSource(new InputStreamReader(new FileInputStream(this.pathToFile.toFile()),"UTF-8"));` – Little Santi Jan 27 '17 at 22:27
0

One problem may be that the Java 8 TransformerFactory's method

public abstract Transformer newTransformer(Source source)
    throws TransformerConfigurationException

.transform is only capable of processing an XSLT-1.0 stylesheet.
But you are trying to process an XSLT-2.0 stylesheet:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> ...

A quick glance at your XSLT reveals that XSLT-1.0 would be sufficient for your needs.

zx485
  • 28,498
  • 28
  • 50
  • 59