我知道这里已多次询问过这个问题,但我遇到了一个不同的问题。在我的例子中,应用程序接收一个以字符串形式传递的格式不正确的dom结构。这是一个示例:
<div class='video yt'><div class='yt_url'>http://www.youtube.com/watch?v=U_QLu_Twd0g&feature=abcde_gdata</div></div>
如您所见,内容格式不正确。现在,如果我尝试使用普通的SAX或DOM解析进行解析,它将抛出一个被理解的异常。
org.xml.sax.SAXParseException:对实体“feature”的引用必须以';'结尾分隔符。
根据要求,我需要阅读本文档,添加一些额外的div标签并将内容作为字符串发回。这通过使用DOM解析器很有效,因为我可以通过输入结构读取并在其所需位置添加其他标记。
我尝试使用像JTidy这样的工具进行预处理然后解析,但这会导致将文档转换为完全成熟的html,这是我不想要的。这是一个示例代码:
StringWriter writer = new StringWriter();
Tidy tidy = new Tidy(); // obtain a new Tidy instance
tidy.setXHTML(true);
tidy.parse(new ByteArrayInputStream(content.getBytes()), writer);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(writer.toString().getBytes()));
// Traverse thru the content and add new tags
....
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
这会将输入完全转换为格式正确的html文档。然后很难手动删除html标签。我尝试的另一个选项是使用SAX2DOM,它也创建了一个HTML文档。这是一个示例代码。
ByteArrayInputStream is = new ByteArrayInputStream(content.getBytes());
Parser p = new Parser();
p.setFeature(IContentExtractionConstant.SAX_NAMESPACE,true);
SAX2DOM sax2dom = new SAX2DOM();
p.setContentHandler(sax2dom);
p.parse(new InputSource(is));
Document doc = (Document)sax2dom.getDOM();
如果有人可以分享他们的想法,我将不胜感激。
由于
答案 0 :(得分:1)
最简单的方法是用相应的xml实体替换xml保留字符。您可以手动执行此操作:
content.replaceAll("&", "&");
如果您不想在解析之前修改字符串,我可以使用SaxParser
以另一种方式建议您,但此解决方案更复杂。基本上你必须:
LexicalHandler
与ContentHandler
ErrorHandler
是不够的) <强>更新强>
根据你的评论,我将添加关于第二个解决方案的一些细节。我写了一个扩展DefaulHandler
(默认实现EntityResolver
,DTDHandler
,ContentHandler
和ErrorHandler
)并实现LexicalHandler
的课程。我已经扩展ErrorHandler
的{{1}}方法(我的实现什么都不做,而不是抛出异常)和fatalError
的{{1}}方法,它与{{1}结合使用} ContentHandler
的方法。
characters
这是我的主要解析你的xml没有很好的形成。 startEntity
非常重要,因为没有它,解析器会抛出LexicalHandler
,尽管public class MyHandler extends DefaultHandler implements LexicalHandler {
private String currentEntity = null;
@Override
public void fatalError(SAXParseException e) throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String content = new String(ch, start, length);
if (currentEntity != null) {
content = "&" + currentEntity + content;
currentEntity = null;
}
System.out.print(content);
}
@Override
public void startEntity(String name) throws SAXException {
currentEntity = name;
}
@Override
public void endEntity(String name) throws SAXException {
}
@Override
public void startDTD(String name, String publicId, String systemId)
throws SAXException {
}
@Override
public void endDTD() throws SAXException {
}
@Override
public void startCDATA() throws SAXException {
}
@Override
public void endCDATA() throws SAXException {
}
@Override
public void comment(char[] ch, int start, int length) throws SAXException {
}
}
为空实现。
setFeature
这个主要打印出div元素的内容,其中包含错误:
SaxParseException
请记住,这是一个适用于您的输入的示例,也许您必须完成它...例如,如果您有一些字符正确转义,您应该添加一些代码行来处理这种情况等。
希望这有帮助。