问题
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)
回答1:
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.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/20434510/transformer-library-that-comes-with-java-converts-spaces-in-file-paths-to-20