Question

Here is a test application that writes out XML Files.

Why are the spaces in my path being converted to %20?

public class XmlTest
{
    public static void main(String[] args)
    {
        String filename = "C:\\New Folder\\test.xml";
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.newDocument();
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            DOMSource source = new DOMSource(doc);

            File xmlFile = new File(filename);
            if (xmlFile.exists())
            {
                xmlFile.delete();
            }
            StreamResult result = new StreamResult(xmlFile);
            transformer.transform(source, result);

        }
        catch (ParserConfigurationException ex)
        {
            ex.printStackTrace();
        }
        catch (TransformerException tfe)
        {
            tfe.printStackTrace();
        }
    }
}

Stacktrace:

java.io.FileNotFoundException: C:\New%20Folder\test.xml (The system cannot find the path specified)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:70)
    at org.apache.xalan.transformer.TransformerIdentityImpl.createResultContentHandler(TransformerIdentityImpl.java:287)
    at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:330)
    at avm.trans.xml.XmlTest.main(XmlTest.java:52)
Was it helpful?

Solution

Try to change this line:

StreamResult result = new StreamResult(xmlFile);

into this:

StreamResult result = new StreamResult(new FileOutputStream(xmlFile));

I have no Idea, why the filename is handled as an URL.

OTHER TIPS

Following from @ChristianKuetbach's answer, it would seem like the argument passed to the StreamResult constructor determines how it will be handled.

From the Oracle docs

public StreamResult(String systemId)  
    Construct a StreamResult from a URL.  
Parameters:  
    systemId - Must be a String that conforms to the URI syntax.

public StreamResult(File f)
   Construct a StreamResult from a File.
Parameters:
   f - Must a non-null File reference.

So initially, I was passing a String path, and so presumably the StreamResult decided to take the initiative to encode it automatically, rather than assuming it is "a String that comforms to the URI syntax".

As a result, passing in a File object told it to handle it as a file path instead of a URL and therefore spaces (and other special characters) were not encoded.

This problem might also occur in cases of paths containing special characters, for which the first answer isn't helping pretty much(with the conversion, that is). For example, in my case the path of my file contained the char "`" that was automatically translated into "%60".

I solved my problem by changing the code line:

StreamResult result = new StreamResult(xmlFile);

result = D:/Work/.../%60Projects/.../xmlFile.xml

into code lines:

StreamResult result = new StreamResult(xmlFile);
result.setSystemId(URLDecoder.decode(xmlFile.toURI().toURL().toString(), "UTF-8"));

result = D:/Work/.../`Projects/.../xmlFile.xml

This overrides the URL encoding problem that's implemented by default within the StreamResult class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top