Java XML: IndexOutOfBoundsException When appending a node - java

Now that I am writing a messenger program. The following code shall store the message history.
Sadly, I've encountered an "IndexOutOfBounds" exception on a line and I've been trying for a whole day,
but still can't figure out the problem.
So here it is.
public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static final String FILE_PATH = "/data/data/com.demo.xmppchat/";
public static Map<Date, String> messagesMap = new TreeMap<Date, String>();
// File should be saved as /username/buddy.xml
public static void writeHistory(String username, String buddy, Map<Date, String> messages)
{
try {
// Check if the file exists. If the file does not exist, create and initiate one.
File file = new File(FILE_PATH + username);
if (!file.exists()) {
file.mkdirs();
}
file = new File(FILE_PATH + username + "/" + buddy + ".xml");
// file.setReadable(true); file.setWritable(true); file.setExecutable(true);
if (!file.exists()) {
file.createNewFile();
initiateHistoryFile(username, buddy);
}
// Now that the XML file should exists as we have created and initialized one.
// TODO:
// Now we modify the XML file
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(file);
Element root = doc.getDocumentElement();
Element rootE = doc.getDocumentElement();
String s = "";
Node n = null;
for (Map.Entry<Date, String> entry : messages.entrySet()) {
// <message>
Element messageE = doc.createElement("message");
rootE.appendChild(messageE);
// Set attribute to <message> element
// messageE.setAttribute("id", "1");
// <from>
Element fromE = doc.createElement("from");
fromE.appendChild(doc.createTextNode(buddy));
messageE.appendChild(fromE);
// <date>
Element dateE = doc.createElement("date");
s = SDF.format(entry.getKey());
n = doc.createTextNode(s);
dateE.appendChild(n);
messageE.appendChild(dateE);
// <text>
Element textE = doc.createElement("text");
s = entry.getValue();
n = doc.createTextNode(s);
textE.appendChild(n);
messageE.appendChild(textE);
root.appendChild(messageE); // <- *** THIS IS WHERE "IndexOutOfBounds" exception OCCURS! ***
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
// Write the file
// FileWriter fileWritter = new FileWriter(file.getName(),true);
// BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
// bufferWritter.write("");
// bufferWritter.close();
} catch (Exception e) {
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_SYSTEM, ToneGenerator.MAX_VOLUME);
toneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP);
e.printStackTrace();
}
}
The Log:
W/System.err(1067): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0 W/System.err(1067): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) W/System.err(1067): at java.util.ArrayList.add(ArrayList.java:143) W/System.err(1067): at org.apache.harmony.xml.dom.InnerNodeImpl.insertChildAt(InnerNodeImpl.java:126) W/System.err(1067): at org.apache.harmony.xml.dom.InnerNodeImpl.appendChild(InnerNodeImpl.java:52) W/System.err(1067): at com.demo.xmppchat.XMLReadWrite.writeHistory(XMLReadWrite.java:113)

Related

I want append data at the end of text file .xml . I use textfield to SetTextContent . Now I want add next tag on file xml

private void bt_create_xml(ActionEvent e) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("University");
doc.appendChild(rootElement);
Element staff = doc.createElement("student");
// add staff to root
rootElement.appendChild(staff);
// add xml attribute
staff.setAttribute("rollno", tf_input_id.getText());
Element name = doc.createElement("fullname");
name.setTextContent(tf_input_fullname.getText());
staff.appendChild(name);
Element code = doc.createElement("code");
code.setTextContent(tf_input_code.getText());
staff.appendChild(code);
Element birthday = doc.createElement("birthday");
birthday.setTextContent(tf_input_birth.getText());
staff.appendChild(birthday);
Element department = doc.createElement("department");
department.setTextContent(tf_input_depart.getText());
staff.appendChild(department);
Element address = doc.createElement("address");
address.setTextContent(tf_input_add.getText());
staff.appendChild(address);
try{
writeXml(doc, System.out);
FileOutputStream out=new FileOutputStream("D:\\JAVA\\XML-CUOIKY\\XML.xml");
writeXml(doc,out);
}catch (Exception exx){
exx.printStackTrace();
}
} catch (ParserConfigurationException ex) {
ex.printStackTrace();
}
}
private static void writeXml(Document doc,
OutputStream output)
throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// pretty print
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(output);
transformer.transform(source, result);
}
"I want append data at the end of text file .xml . I use textfield to SetTextContent . Now I want add next tag on file xml"

In java how to filter out a child node in xml depending on the string

I'm writing a java program that is reading from a file path and creates a sitemap.xml.
The sitemap.xml will look like this
<loc>http://localhost/content/falcon/en/index/auto</loc>
<lastMod>2019-12-05</lastMod>
<changefreq>weekly</changefreq>
<priority>0.0</priority>
<testing>admin</testing>
</url>
<url>
<loc>
http://localhost/content/falcon/en/index/auto/coverage
</loc>
<lastMod>2019-09-11</lastMod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
<testing>admin</testing>
</url>
<url>
<loc>
http://localhost/content/falcon/en/index/auto/collectible
</loc>
<lastMod>2019-01-17</lastMod>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
<testing>ben.snedeker#tallwave.com</testing>
</url>
<url>
<loc>
http://localhost/content/falcon/en/index/auto/collectible/features-discounts
</loc>
<lastMod>2016-12-30</lastMod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
<testing>usw8453</testing>
</url>
Inside the tags<loc> </loc>
Contains a urlthat is originally a string, depending on the url I want to be able to filter out the whole node including its siblings tags like <lastMod> <changefrequency> <priority> etc
This is the java that is writing to the xml sheet
Resource resource = resourceResolver.getResource(sitemapRootPath);
if(resource != null) {
response.setContentType("text/xml;charset=UTF-8");
Page page = resource.adaptTo(Page.class);
Iterator<Page> pageIterator = page.listChildren();
//Initializing the XML document before writing data into the file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
LOG.info("Inside Try");
builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element rootElement = document.createElement("urlset");
rootElement.setAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
document.appendChild(rootElement);
for(int i = 0; i < staticPageData.length; i ++) {
createXMLNodeForStaticPages(document, rootElement, request, staticPageData[i]);
}
while(pageIterator.hasNext()) {
createXMLNode(document, rootElement, request, pageIterator);
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
//initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(document);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
out.print(xmlString);
This is the method being called by the while loop up above. It writes the xml for the children pages as well in the bottom for loop.
public void createXMLNode(Document document, Element rootElement, SlingHttpServletRequest request, Iterator<Page> pageIterator) {
Element headElement = document.createElement("url");
Element locElement = document.createElement("loc");
Element lastModElement = document.createElement("lastMod");
Element changefreqElement = document.createElement("changefreq");
Element priorityElement = document.createElement("priority");
Element testingElement = document.createElement("testing");
Node locElementNode = locElement;
Node lastModElementNode = lastModElement;
Node changefreqElementNode = changefreqElement;
Node priorityElementNode = priorityElement;
Node testingElementNode = testingElement;
Page childPage = pageIterator.next();
String location = request.getScheme() + "://" + request.getServerName() + childPage.getPath();
locElementNode.setTextContent(location);
LOG.error("childPage.getLastModified()" + childPage.getLastModified());
if(null != childPage.getLastModified()) {
Date date = childPage.getLastModified().getTime();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
try {
dateFormat.parse("2019-07-15");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lastModElementNode.setTextContent(dateFormat.format(date));
}
String editor = childPage.getLastModifiedBy();
changefreqElementNode.setTextContent("weekly");
priorityElementNode.setTextContent(PriorityValue(location));
testingElementNode.setTextContent(editor);
rootElement.appendChild(headElement);
headElement.appendChild(locElementNode);
headElement.appendChild(lastModElementNode);
headElement.appendChild(changefreqElementNode);
headElement.appendChild(priorityElementNode);
headElement.appendChild(testingElementNode);
Iterator<Page> childPageIterator = childPage.listChildren();
while(childPageIterator.hasNext()) {
createXMLNode(document, rootElement, request, childPageIterator);
}
}
I want to be able to skip a whole child node when a certain string is read.
for example orignally the attribute inside a loc is just a string that is read from the file path where this java class is reading from.
String location = request.getScheme() + "://" + request.getServerName() + childPage.getPath();
locElementNode.setTextContent(location);
it gets put in a variable location then we set locElementNode with that value.
I want to be able to filter out the whole node when a reads a certain url string. The while loop should skip to the next element that is next .
Well, all you need to do is just add logic to check returned string before creating any elements and appending them
public void createXMLNode(Document document, Element rootElement, SlingHttpServletRequest request, Iterator<Page> pageIterator) {
String location = request.getScheme() + "://" + request.getServerName() + childPage.getPath();
if (location.equals("<banned url>") {
return;
}
Element headElement = document.createElement("url");
Element locElement = document.createElement("loc");
Element lastModElement = document.createElement("lastMod");
Element changefreqElement = document.createElement("changefreq");
Element priorityElement = document.createElement("priority");
Element testingElement = document.createElement("testing");
Node locElementNode = locElement;
Node lastModElementNode = lastModElement;
Node changefreqElementNode = changefreqElement;
Node priorityElementNode = priorityElement;
Node testingElementNode = testingElement;
Page childPage = pageIterator.next();
locElementNode.setTextContent(location);
....

Creating xml file containing multiple xml content stored within hashmap using java

I intend to create xml files of same tags within a bigger xml file from a java object. i.e. i need to append the xml file every time running over a loop.
I have stored the xml field name and values as key/value pairs in HashMap structure.
Expected: multiple xml content within a single large xml file
Actual: The file is produced but none of the tags/values are written. Just the start and end tag of the whole file is being printed
Code:
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("add");
doc.appendChild(rootElement);
// document elements
Element document = doc.createElement("doc");
rootElement.appendChild(document);
Iterator<Entry<String, String>> itr1 = hMap.entrySet().iterator();
System.out.println("-----------------Page start---------------------");
while (itr1.hasNext()) {
Map.Entry pairs = (Map.Entry)itr1.next();
System.out.println(pairs.getKey() + "=== " + pairs.getValue());
//itr1.remove(); // avoids a ConcurrentModificationException
//String s = pairs.getKey().toString();
Element field = doc.createElement("field");
field.appendChild(doc.createTextNode(pairs.getValue().toString()));
field.setAttribute("name", pairs.getKey().toString());
document.appendChild(field);
}
System.out.println("-------------------Page stop------------------------");
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("D:\\Infoboxinxml.xml"));
// Output to console for testing
//StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
System.out.println("File saved!");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
This will be easiest using a modern DOM parser such as JDOM.
Document document = new Document();
Element root = new Element("add");
Element doc = new Element("doc");
document.addContent(root);
root.addContent(doc);
Map<String, String> map = new LinkedHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
for (Map.Entry<String, String> pair : map.entrySet()) {
doc.addContent(
new Element("field")
.setAttribute("name", pair.getKey())
.setText(pair.getValue())
);
}
System.out.println(new XMLOutputter(Format.getPrettyFormat()).outputString(document));

append node to an xml in Java

I can't append correctly some info to my xml file. That's the scrivi function
public String scrivi (Document doc, File dest)
{
try
{
DOMSource sorgente = new DOMSource (doc);
StreamResult sr = new StreamResult (dest);
TransformerFactory tf =
TransformerFactory.newInstance();
Transformer transf = tf.newTransformer();
transf.transform (sorgente, sr);
return "Tutto ok";
}
catch (TransformerConfigurationException tce)
{
System.out.println(tce.getMessage());
return "<h1> Config </h1>";
}
catch (TransformerException te)
{
System.out.println(te.getMessage());
return "<h1> Transformer Errore </h1>";
}
}
and tath is my code:
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(getClass().getResourceAsStream("/azioni.xml"));
Element root = document.getDocumentElement();
Element new_azione = document.createElement("azione");
Element id = document.createElement("id_azione");
id.setTextContent(id_azione);
Element nome = document.createElement("nome_azione");
nome.setTextContent(nome_azione);
Element prezzo_a = document.createElement("prezzo");
prezzo_a.setTextContent(prezzo);
new_azione.appendChild(id);
new_azione.appendChild(nome);
new_azione.appendChild(prezzo_a);
document.getDocumentElement().appendChild(new_azione);
String nomexmlOut="/azioni.xml";
File filedest = new File(nomexmlOut);
out.println(this.scrivi(document, filedest));
}
I get the error Transformer Errore ... how can I solve? what's Wrong?
* UPDATE *
Error Info
java.io.FileNotFoundException: /azioni.xml (Permission denied)
Hard to tell without actual exception trace or message, but my guess is that your problem is the ouput stream.
File("/azioni.xml");
is not the same as
getClass().getResourceAsStream("/azioni.xml")
Try with directing the output to system out and see if it works. i.e. declare scrivi
public String scrivi (Document doc, OutputStream out)
and call it with
scrivi(document, System.out);
UPDATE:
To write to the same file location, try something like this (untested)
File out = new File(getClasss().getResource("...").getFile());
and make sure that you close the input stream that you originally read from, before trying to write.

Creating an xml document in android

So I'm trying to create an xml document in my android application. I'm using the code that I used when writing a java application. I tried as shown below:
public void createxml() throws SAXException, IOException {
try {
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "images" + File.separator + "newxml.xml");
DocumentBuilderFactory docFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(file);
// root elements
// Document doc = docBuilder.newDocument();
// Element rootElement = doc.get
// doc.appendChild(rootElement);
Node node = doc.getDocumentElement();
// staff elements
Element outfit = doc.createElement("outfit");
node.appendChild(outfit);
// set attribute to staff element
/*
* Attr attr = doc.createAttribute("id"); attr.setValue("1");
* staff.setAttributeNode(attr);
*/
// shorten way
// staff.setAttribute("id", "1");
// firstname elements
if (savename.equals("none")) {
} else {
Element nameelement = doc.createElement("name");
nameelement.appendChild(doc.createTextNode(savename));
outfit.appendChild(nameelement);
}
if (hatloc.equals("none")) {
} else {
Element hatelement = doc.createElement("hat");
hatelement.appendChild(doc.createTextNode(hatloc));
outfit.appendChild(hatelement);
}
if (shirtloc.equals("none")) {
} else {
Element shirtelement = doc.createElement("shirt");
shirtelement.appendChild(doc.createTextNode(shirtloc));
outfit.appendChild(shirtelement);
}
if (pantloc.equals("none")) {
} else {
Element pantselement = doc.createElement("pants");
pantselement.appendChild(doc.createTextNode(pantloc));
outfit.appendChild(pantselement);
}
if (shoeloc.equals("none")) {
} else {
Element shoeselement = doc.createElement("shoes");
shoeselement.appendChild(doc.createTextNode(shoeloc));
outfit.appendChild(shoeselement);
}
if (acc1loc.equals("none")) {
} else {
Element accelement = doc.createElement("accessories");
accelement.appendChild(doc.createTextNode(acc1loc));
outfit.appendChild(accelement);
}
if (acc2loc.equals("none")) {
} else {
Element acc2element = doc.createElement("accessories2");
acc2element.appendChild(doc.createTextNode(acc2loc));
outfit.appendChild(acc2element);
}
if (beltloc.equals("none")) {
} else {
Element beltelement = doc.createElement("belt");
beltelement.appendChild(doc.createTextNode(beltloc));
outfit.appendChild(beltelement);
}
if (dressloc.equals("none")) {
} else {
Element dresselement = doc.createElement("dress");
dresselement.appendChild(doc.createTextNode(dressloc));
outfit.appendChild(dresselement);
}
if (jacketloc.equals("none")) {
} else {
Element jacketelement = doc.createElement("jacket");
jacketelement.appendChild(doc.createTextNode(jacketloc));
outfit.appendChild(jacketelement);
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(
new File(Environment.getExternalStorageDirectory()
+ File.separator + "images" + File.separator
+ "newxml.xml"));
transformer.transform(source, result);
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
hatloc = "none";
shirtloc = "none";
pantloc = "none";
shoeloc = "none";
acc1loc = "none";
acc2loc = "none";
beltloc = "none";
dressloc = "none";
jacketloc = "none";
savename = "none";
}
Everything worked fine until I got to this section below. I think it's the section where the xml file i created gets written. Does anyone know of a way to do this that works in android?
The code breaks with the TransformerFactory, Transformer, DOMSource, StreamResult and TransformerException.
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(
new File(Environment.getExternalStorageDirectory() + File.separator
+ "images" + File.separator + "newxml.xml"));
transformer.transform(source, result);
I think that the Transfomer class is not included in the Android API you're using.
To avoid using Transformer you should manually iterate over your xml tree, otherwise you can rely on some external libraries. You should take a look here.

Categories