Hi all, I have been working at home on a small project to help my Java Jedi training. :-)
My app saves quotes from authors in an xml file.
I have a class [XmlRepository extends Thread] that holds control of an xml file to handle requests for Nodes.
When I remove a node I get a Line Space above the node that was removed, or better put my node gets replaced by a empty line.
Pretty print or correct Node removing.
part of my xml is like this (I have resumed it for readability):
<entities forUser="ffffffff-ffff-ffff-ffff-ffffffffffff">
<quotes/>
<authors>
<author id="f156c570-c676-4d69-9b15-ae7d859ff771" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Poe</lastNames>
<firstNames>Edgar Allan</firstNames>
</author>
<author id="35dc0c5a-3813-4a10-af49-8d4ea1c2cee0" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Wilde</lastNames>
<firstNames>Oscar</firstNames>
</author>
<author id="317f72ea-add6-4bd2-8c63-d8b373a830ab" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Christie</lastNames>
<firstNames>Agatha</firstNames>
</author>
<author id="28047c89-b647-4c40-b6c7-677feaf2dfda" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Shakespeare</lastNames>
<firstNames>William</firstNames>
</author>
</authors>
</entities>
If I remove A Node ( Edgar Allan Poe (1st in this case)) the resulting Xml when saved is like this (I have added the space indentation just as it is outputted by my code):
<entities forUser="ffffffff-ffff-ffff-ffff-ffffffffffff">
<quotes/>
<author id="35dc0c5a-3813-4a10-af49-8d4ea1c2cee0" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Wilde</lastNames>
<firstNames>Oscar</firstNames>
</author>
<author id="317f72ea-add6-4bd2-8c63-d8b373a830ab" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Christie</lastNames>
<firstNames>Agatha</firstNames>
</author>
<author id="28047c89-b647-4c40-b6c7-677feaf2dfda" languageCode="en" regenerateAs="com.fdt.cognoscere.entities.sources.Author">
<lastNames>Shakespeare</lastNames>
<firstNames>William</firstNames>
</author>
</authors>
</entities>
this is how I initialize the XML DOM Handlers, and the method for removing a Node:
/**
* Initializes factory instances and member variables.
*/
private void initialize() {
//obtain an instance of a documentFactory create a document documentBuilder
this.documentFactory = DocumentBuilderFactory.newInstance();
//Configure the documentFactory to be name-space aware and validate trough an xsd file
this.documentFactory.setNamespaceAware(true);
this.documentFactory.setValidating(true);
this.documentFactory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
try {
//obtain an instance of an XPathFactory
this.xpathFactory = XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI);
//obtain an instance of the xpath evaluator object
this.xpathEvaluator = this.xpathFactory.newXPath();
//set namespace mapping configurations
NamespaceContextMap namespaceMappings = new NamespaceContextMap();
namespaceMappings.put("xml", "http://www.w3.org/XML/1998/namespace");
namespaceMappings.put("xmlns", "http://www.w3.org/2000/xmlns/");
namespaceMappings.put("xsd", "http://www.w3.org/2001/XMLSchema");
namespaceMappings.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
namespaceMappings.put(this.schemaNamespaceMapping, this.schemaNamespace);
//add mappings
this.xpathEvaluator.setNamespaceContext(namespaceMappings);
} catch (XPathFactoryConfigurationException ex) {
Logger.getLogger(XmlRepository.class.getName()).log(Level.SEVERE, null, ex);
}
try {
//obtain a trasformer factory to save the file
this.transformerFactory = TransformerFactory.newInstance();
this.transformerFactory.setAttribute("indent-number", 4);
//obtain the transforme
this.transformer = this.transformerFactory.newTransformer();
//setup transformer
this.transformer.setOutputProperty(OutputKeys.METHOD, "xml");
this.transformer.setOutputProperty(OutputKeys.INDENT, "yes");
this.transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text");
this.transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
} catch (TransformerConfigurationException tcex) {
Logger.getLogger(XmlRepository.class.getName()).log(Level.SEVERE, null, tcex);
}
}
/**
* Removes a node by evaluating the XPATH expression.
* @param xpath A String instance with the XPATH expression representing the element to remove.
* @throws com.fdt.cognoscere.storage.exceptions.UnableToRemoveException When an exception occurs that prevents the repository to execute the remove statement.
*/
public void removeNode(final String xpath) throws UnableToRemoveException {
Node nodeToRemove = null;
Node parentNode = null;
//verify xpath
if (xpath == null)
throw new IllegalArgumentException("The xpath argument cannot be null.");
//verify that the repository is loaded
if (!this.loaded)
throw new IllegalStateException("The XmlRepository faild to load properly and it is in an invalid state. It cannot perfom any operation.");
try {
//get the node to remove out of the xpath expression
nodeToRemove = this.getNode(xpath);
//throw an exception if no node was found to remove
if (nodeToRemove == null)
throw new UnableToFindException("The node element trying to be remove does not exist.");
//obtain the parent node to remove its child
parentNode = nodeToRemove.getParentNode();
//remove the node from the parent node
nodeToRemove = parentNode.removeChild(nodeToRemove);
} catch.......removed to save space{
} finally {
//normalize document
this.document.normalize();
}
}
Please tell me if I could do this better,
thanks,
f(t)