patternjavaMinor
Handling various types of nodes when traversing a DOM tree
Viewed 0 times
typeshandlingnodestraversingdomwhenvarioustree
Problem
How to minimize the following code using java's features ... looking for some workaround with the switch-case statement
I've seen several question regarding switch-case design pattern / best practices but because I am new to java, I am having difficulties in implementing them.
Here is the code:
I've seen several question regarding switch-case design pattern / best practices but because I am new to java, I am having difficulties in implementing them.
Here is the code:
protected void readTree(Node node, Branch current)
{
Element element = null;
Document document = null;
if(current instanceof Element)
{
element = (Element) current;
}
else
{
document = (Document) current;
}
String nodeVal = node.getNodeValue();
String nodeName = node.getNodeName();
switch(node.getNodeType())
{
case ELEMENT_NODE:
readElement(node, current);
break;
case PROCESSING_INSTRUCTION_NODE:
if(current instanceof Element)
{
element.addProcessingInstruction(nodeName, nodeVal);
break;
}
document.addProcessingInstruction(nodeName, nodeVal);
break;
case COMMENT_NODE:
if(current instanceof Element)
{
element.addComment(nodeVal);
break;
}
document.addComment(nodeVal);
break;
case DOCUMENT_TYPE_NODE:
DocumentType domDocType = (DocumentType) node;
document.addDocType(domDocType.getName(), domDocType.getPublicId(), domDocType.getSystemId());
break;
case TEXT_NODE:
element.addText(nodeVal);
break;
case CDATA_SECTION_NODE:
element.addCDATA(nodeVal);
break;
case ENTITY_REFERENCE_NODE:
if(node.getFirstChild() != null)
{
element.addEntity(nodeName, node.getFirstChild().getNodeValue());
break;
}
element.addEntity(nodeName, "");
break;
case ENTITY_NODE:
element.addEntity(nodeName, nodeVal);
break;
default:
System.out.println("WARNING: Unknown node type: " + node.getNodeType());
}
}Solution
Consider creating an object which can handle each case:
You can then populate a map, like this, to look up the appropriate handler for a node:
and then...
I don't think this makes the code shorter, but it does make the code more maintainable. Each object has a single, clear responsibility, and you don't have to deal with issues like fall-through cases, or state getting mingled between different handlers. You could conceivably invent new handlers without actually changing the implementation of the
interface NodeHandler {
void handle(Node node, Element current, ...);
}
class ElementHandler implements NodeHandler {
public void handle(Node node, Element current, ...) {
readElement(node, current);
}
}You can then populate a map, like this, to look up the appropriate handler for a node:
private static Map handlerMap;
static {
handlerMap = new HashMap();
handlerMap.put(Node.ELEMENT_NODE, new ElementHandler());
//...
}and then...
handlerMap.get(node.getNodeType()).handle(...);I don't think this makes the code shorter, but it does make the code more maintainable. Each object has a single, clear responsibility, and you don't have to deal with issues like fall-through cases, or state getting mingled between different handlers. You could conceivably invent new handlers without actually changing the implementation of the
readTree() method, or impacting the behavior of existing handlers.Code Snippets
interface NodeHandler {
void handle(Node node, Element current, ...);
}
class ElementHandler implements NodeHandler {
public void handle(Node node, Element current, ...) {
readElement(node, current);
}
}private static Map<Integer, NodeHandler> handlerMap;
static {
handlerMap = new HashMap<Integer, NodeHandler>();
handlerMap.put(Node.ELEMENT_NODE, new ElementHandler());
//...
}handlerMap.get(node.getNodeType()).handle(...);Context
StackExchange Code Review Q#10273, answer score: 8
Revisions (0)
No revisions yet.