我是使用Java和SAX解析器进行XML解析的新手。我有一个非常大的XML文件,因为它的大小我被建议使用SAX解析器。我已经完成了部分任务的解析,它按预期工作。现在,XML作业还剩下一个任务:根据用户的请求删除/更新一些节点。
我可以按名称找到所有标签,更改data
属性等。如果我能够使用SAX执行这些操作,也可以删除。
示例XML描述了某些情况下的某些功能。用户的输入是“案例”的名称(case1
,case2
)。
<ruleset>
<rule id="1">
<condition>
<case1>somefunctionality</case1>
<allow>true</allow>
</condition>
</rule>
<rule id="2">
<condition>
<case2>somefunctionality</case2>
<allow>false</allow>
</condition>
</rule>
</ruleset>
如果用户想要删除其中一种情况(例如case1
)而不仅仅是case1
代码,则必须删除完整的rule
代码。如果要删除case1
,XML将变为:
<ruleset>
<rule id="2">
<condition>
<case2>somefunctionality</case2>
<allow>false</allow>
</condition>
</rule>
</ruleset>
我的问题是,这可以使用SAX完成吗?此时我无法使用DOM或任何其他解析器。只有其他选择更糟糕:字符串搜索。如何使用SaxParser完成?
答案 0 :(得分:6)
尝试
XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
private boolean skip;
@Override
public void startElement(String uri, String localName, String qName, Attributes atts)
throws SAXException {
if (qName.equals("rule")) {
if (atts.getValue("id").equals("1")) {
skip = true;
} else {
super.startElement(uri, localName, qName, atts);
skip = false;
}
} else {
if (!skip) {
super.startElement(uri, localName, qName, atts);
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (!skip) {
super.endElement(uri, localName, qName);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (!skip) {
super.characters(ch, start, length);
}
}
};
Source src = new SAXSource(xr, new InputSource("test.xml"));
Result res = new StreamResult(System.out);
TransformerFactory.newInstance().newTransformer().transform(src, res);
输出
<?xml version="1.0" encoding="UTF-8"?><ruleset>
<rule id="2">
<condition>
<case2>somefunctionality</case2>
<allow>false</allow>
</condition>
</rule>
</ruleset>
答案 1 :(得分:0)
您需要构建的是SAX事件缓冲区。
当您来到一个<rule>
元素时,您需要保存它(或重新生成它所需的信息)以及它与您要删除的“案例”之间发生的所有其他事件。
如果您保存的“规则”与需要删除的规则相同,只需丢弃信息并继续。
如果您保存的“规则”不是需要删除的规则,则应重新生成已保存并继续的sax事件。
答案 2 :(得分:0)
SAX最常用于读取/解析XML。但是有一篇关于如何使用SAX来编写文件的文章。看来章节可在线获取 - 见:
http://xmlwriter.net/sample_chapters/Professional_XML/31100604.shtml
[这篇文章的日期是1999年所以它使用旧版本的SAX,但概念仍然适用]
基本思路是创建自定义DocumentHandler / ContentHandler。每当它收到SAX事件时,它就会序列化并将事件写入流/文件/其他任何事件。因此,您将输入文档用作sax事件的来源,并将这些事件转发到XMLOutputter。
困难的部分是,您可以将XML文档解析为SAX事件流,驱动XMLOutputter并生成输入文件的精确副本。一旦你开始工作,你可以进入编辑逻辑,在那里读取规则并使用它们来修改输出文件。
它比DOM,JDOM,XSLT等工作要多得多,但它可能对您的情况有所帮助,因为您永远不必将整个文档存储在内存中。