Reputation: 225
Hello I'm trying to parse an xml file using SAX and filter it based on an element value and save the result in another file.
the XML file example:
<ruleset>
<rule>
<condition>
<case1>String testing</case1>
<allow>true</allow>
</condition>
</rule>
<rule>
<condition>
<case2>String test</case2>
<allow>false</allow>
</condition>
</rule>
</ruleset>
I want the result file to be as follows
<ruleset>
<rule>
<condition>
<case2>String test</case2>
<allow>false</allow>
</condition>
</rule>
</ruleset>
Since the tag has the value "false", So mainly I want to filter the loop element based on the element's value
The code till now helps me filter the all the elements based on the parent element but not on the element.
final String splitElement = "Rule";
XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
private boolean skip;
public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes atts)
throws SAXException {
if (qName.equals(splitElement)) {
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);
}
}
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(
"SourceFilePath"));
StreamResult res = new StreamResult(new File(
"DestinantionFilePath"));
TransformerFactory.newInstance().newTransformer().transform(src, res);
Is it possible to do that using a SAX parser and only keep the "rules" that have an as false ?
Upvotes: 0
Views: 400
Reputation: 163302
Not easy because it requires lookahead - you can't decide what do with a rule
start tag until you see the allow
value some time later. The easiest way would be start building a DOM(or DOM-like) tree for each rule, and when you hit the rule
end tag, decide whether to keep it or discard it.
If you want a streaming solution to this problem using XSLT 3.0, it's
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="rule">
<xsl:sequence select="copy-of(.)[condition/allow='true']"/>
</xsl:template>
Upvotes: 1