Re: XML Parsing Troubles
<jackroofman@gmail.com> wrote in message
news:1176231150.062063.147030@q75g2000hsh.googlegroups.com...
It seems I've been defeated by the automatic formatting of the posts.
Shows up fine here. If you're using GoogleGroups, try using the "raw"
view to see what other usenet users actually see.
With each removal of the <song> nodes, a blank line is left. That is,
the last example above has four blank lines, not just one. I have
managed to avoid the whole issue of removing every other line; it
readjusts the count with each Node removed, so once Node 1 is removed
and the i variable goes on to 2, it's actually acting on what WAS the
third Node. A simple i--; fixed that, but the excessive blank lines
still remain. What's the best way to go about removing those?
"Best" way is probably to define a DTD or Schema explicitly stating
the format of your XML format, and in what locations is whitespace not
significant, and places where it IS significant. For example, in your
<song> tag, whitespace IS significant. The elements <song>some file
name.mp3</song> and <song>some file name.mp3</song> point to two
different files on the file system.
Failing that, you can always write a hack:
<SSCCE>
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
public class XMLTest {
public static void main(final String[] args) throws Exception {
final Document document = inputXML();
doProcessing(document);
stripWhitespace(document.getDocumentElement());
outputXML(document);
}
private static Document inputXML() throws ParserConfigurationException,
SAXException, IOException {
final DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
final Document document = builder.parse(new File("songs.xml"));
return document;
}
private static void doProcessing(final Document document) {
final NodeList songNodes = document.getElementsByTagName("song");
while (songNodes.getLength() > 0) {
final Node songNode = songNodes.item(0);
songNode.getParentNode().removeChild(songNode);
}
}
private static void outputXML(final Document document) throws
TransformerFactoryConfigurationError, TransformerConfigurationException,
TransformerException {
final TransformerFactory tFactory = TransformerFactory.newInstance();
final Transformer transformer = tFactory.newTransformer();
final DOMSource source = new DOMSource(document);
final StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
}
private static void stripWhitespace(Node e) {
NodeList children = e.getChildNodes();
List<Node> childrenToRemove = new ArrayList<Node>();
for (int i = 0; i < children.getLength(); i++) {
final Node currElement = children.item(i);
if (currElement.getNodeType() == Node.TEXT_NODE) {
Text t = (Text) currElement;
if (t.getData().trim().length() == 0) {
childrenToRemove.add(t);
}
}
}
for (Node n: childrenToRemove) {
e.removeChild(n);
}
for (int i = 0; i < children.getLength(); i++) {
stripWhitespace(children.item(i));
}
}
}
</SSCCE>
This program expects your data to be in the song.xml file, and outputs
the results to standard out.
Notice I also provide two alternative tricks for removing elements
without resorting to "i--;" which I think will be bug prone.
You'll probably want to modify stripWhitespace() to do something a bit
more intelligent than just obliterating any text elements which contain
only whitespace.
- Oliver