2

我正在使用 dom4j 读取 XML 文件。该文件如下所示:

...
<Field>&#13;&#10; hello, world...</Field>
...

我将文件读SAXReaderDocument. 当我getText()在节点上使用时,我获得以下字符串:

\r\n hello, world...

我做了一些处理,然后使用asXml(). 但是字符没有像原始文件中那样转义,这会导致使用该文件的外部系统出错。

&#13;&#10;写入文件时如何转义特殊字符并拥有?

4

4 回答 4

1

你不能轻易。那些不是“逃脱”,它们是“角色实体”。它们是 XML 的基本部分。Xerces 对“未解析的实体”有一些非常复杂的支持,但我怀疑它是否适用于这些,而不是 DTD 中定义的物种。

于 2010-02-12T13:20:34.200 回答
1

这取决于你得到什么和你想要什么(见我之前的评论。)

SAX 阅读器没有做错任何事情——您的 XML 给了您一个文字换行符。如果您控制此 XML,则需要插入 \(反斜杠)字符,而不是换行符,后跟“r”或“n”字符(或两者)。

如果您不控制此 XML,那么在您取回字符串后,您需要将换行符文字转换为“\r\n”。在 C# 中,它类似于:

myString = myString.Replace("\r\n", "\\r\\n");
于 2010-02-12T13:21:56.687 回答
1

XML 实体在 DOM 中被抽象出来。内容使用 String 公开,无需担心编码——在大多数情况下,这正是您想要的。

但是 SAX 对如何处理实体有一些支持。您可以尝试XMLReader使用自定义创建 a EntityResolver#resolveEntity,并将其作为参数传递给SAXReader. 但我觉得它可能行不通:

Parser 将在打开除顶级文档实体之外的任何外部实体(包括外部 DTD 子集、DTD 内引用的外部实体和文档元素内引用的外部实体)之前调用此方法

否则,您可以尝试LexicalHandler为 SAX 配置一个在遇到实体时收到通知的方式。JavadocLexicalHandler#startEntity说:

报告一些内部和外部 XML 实体的开始。

您将无法更改解析,但这可能仍然有帮助。

编辑

您必须使用dom4j 提供的SAXReader和读写 XML 。XMLWriter请参阅读取 XML 文件写入 XML 文件。不要asXml()自己使用和转储文件。

FileOutputStream fos = new FileOutputStream("simple.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(fos, format);
writer.write(doc);
writer.flush();
于 2010-02-12T13:35:04.420 回答
0

您可以预处理输入流以替换&为 eg [$AMPERSAND_CHARACTER$],然后使用 dom4j 进行处理,并对输出流进行后处理以进行反向替换。

示例(使用streamflyer):

import com.github.rwitzel.streamflyer.util.ModifyingReaderFactory;
import com.github.rwitzel.streamflyer.util.ModifyingWriterFactory;

// Pre-process
Reader originalReader = new InputStreamReader(myInputStream, "utf-8");
Reader modifyingReader = new ModifyingReaderFactory().createRegexModifyingReader(originalReader, "&", "[\\$AMPERSAND_CHARACTER\\$]");

// Read and modify XML via dom4j
SAXReader xmlReader = new SAXReader();
Document xmlDocument = xmlReader.read(modifyingReader);
// ...

// Post-process
Writer originalWriter = new OutputStreamWriter(myOutputStream, "utf-8");
Writer modifyingWriter = new ModifyingWriterFactory().createRegexModifyingWriter(originalWriter, "\\[\\$AMPERSAND_CHARACTER\\$\\]", "&");

// Write to output stream
OutputFormat xmlOutputFormat = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(modifyingWriter, xmlOutputFormat);
xmlWriter.write(xmlDocument);
xmlWriter.close();

您还可以使用FilterInputStream / FilterOutputStreamPipedInputStream / PipedOutputStreamProxyInputStream / ProxyOutputStream进行预处理和后处理。

于 2016-11-08T13:42:10.227 回答