编辑:发现我的问题!
发现我的问题!
我实际上有两个调用来创建新文件:
if (!f.exists())
f.createNewFile();
和
Result result = new StreamResult(f);
transformer.transform(source, result);
文件名中没有空格,一切都很顺利,因为它们都处理了相同的文件。但是,使用空格,StreamResult 将文件名编码为 URL(因此用 %20 替换空格),而 createNewFile() 没有。修复很简单。我删除了
f.createNewFile();
行并添加:
result.setSystemId(java.net.URLDecoder.decode(result.getSystemId(), "UTF-8"));
因此用空格正确写入文件名。
原始问题:
我正在尝试编写一个 XML 文件,但如果文件名中有空格,则以下代码似乎会生成两个不同的文件。第一个文件将用空格正确命名,另一个文件将其空格替换为 %20。只有替换了空格的文件 (%20) 似乎具有正确的 XML 内容。它似乎与 URL 编码有关,但我似乎无法弄清楚它发生在哪里。
public String export(Context ctx) {
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
try {
icBuilder = icFactory.newDocumentBuilder();
Document doc = icBuilder.newDocument();
Element mainRootElement = doc.createElement("deck");
mainRootElement.setAttribute("game",
"0f38e453-26df-4c04-9d67-6d43de939c77");
doc.appendChild(mainRootElement);
// identity card is located on top of the XML file
// identity section
Element identitySection = doc.createElement("section");
identitySection.setAttribute("name", CardTypes.IDENTITY);
mainRootElement.appendChild(identitySection);
identitySection
.appendChild(createNode(doc, 1, identity.getTitle()));
// stack / r&d section
Element deckSection = doc.createElement("section");
deckSection.setAttribute("name", "R&D / Stack");
// add all the cards!
for (DeckItem item : cards) {
NRCard card = item.getCard();
deckSection.appendChild(createNode(doc, item.getAmount(),
card.getTitle()));
}
mainRootElement.appendChild(deckSection);
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
if (Utilities.ExternalStorageWritable()) {
String root = Environment.getExternalStorageDirectory()
.toString();
File f = new File(root + "/TheToolbox/decks/" + this.deckName
+ ".o8d");
if (!f.getParentFile().exists())
f.getParentFile().mkdirs();
if (!f.exists())
f.createNewFile();
Result result = new StreamResult(f);
transformer.transform(source, result);
System.out.println("Export completed");
} else {
throw new Exception("External storage not writable");
}
} catch (Exception e) {
Log.e("TB error", e.getMessage());
}
return this.deckName;
}