SAXReader notre-escape字符

时间:2010-02-12 13:14:16

标签: java dom dom4j

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

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

我将文件SAXReader读入Document。当我在节点上使用getText()时,我获得了以下字符串:

\r\n hello, world...

我做了一些处理,然后使用asXml()写了另一个文件。但是,原始文件中的字符不会被转义,导致使用该文件的外部系统出错。

如何在编写文件时转义特殊字符并使用&#13;&#10;

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

这取决于你得到的和你想要的东西(见我以前的评论。)

SAX阅读器没有任何错误 - 您的XML正在为您提供文字换行符。如果您控制此XML,则需要在“r”或“n”字符(或两者)之后插入\(反斜杠)字符而不是换行符。

如果你不控制这个XML,那么在你收回你的字符串后,你需要将换行符的字面转换为“\ r \ n”。在C#中,它将类似于:

myString = myString.Replace("\r\n", "\\r\\n");

答案 2 :(得分:1)

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

但SAX对实体的处理方式有一些支持。您可以尝试使用自定义XMLReader创建EntityResolver#resolveEntity,并将其作为参数传递给SAXReader。但我认为它可能不起作用:

  

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

否则,您可以尝试为SAX配置LexicalHandler,以便在遇到实体时得到通知。 LexicalHandler#startEntity的Javadoc说:

  

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

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

修改

您必须使用dom4j提供的SAXReaderXMLWriter来读写XML。请参阅reading a XML filewriting an XML file。不要使用asXml()并自行转储文件。

FileOutputStream fos = new FileOutputStream("simple.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(fos, format);
writer.write(doc);
writer.flush();

答案 3 :(得分:0)

您可以预处理输入流,以将&替换为例如[$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进行预处理和后处理