Problem loading a XML file using Dom parser - java

I am new with Java programming and I have problem reading XML-file. I am trying to save information from XML using DOM parser. I load the xml into a Document and then trying to save all the schedules of a radio channel in a NodeList. but the program saves repeatedly just infromation of the first node. Where is the problem with my code ?
NodeList episodeElement = doc.getElementsByTagName("schedule");
for (int i = 0; i < episodeElement.getLength(); i++) {
Node n = episodeElement.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE && getSize(doc) != 0) {
Element e = (Element) n;
String title = e.getElementsByTagName("title").item(i).getTextContent();
NodeList nd = e.getElementsByTagName("description");
String description;
if (nd.getLength() > 0) {
description = nd.item(i).getTextContent();
}else {
description = null;
}
String startTime = e.getElementsByTagName("starttimeutc").item(i).getTextContent();
String endTime = e.getElementsByTagName("endtimeutc").item(i).getTextContent();
Program prog = new Program(id, title, description, startTime, endTime);
System.out.println(startTime);
programs.add(i, prog);
}
else {
System.out.println("No schedules found");
}
}

You haven't used .getChildNodes() method to traverse a layer down the tag and looped around that, that's why it is just fetching you information of the first node.
Visit this link and u can find an excellent example.
https://www.youtube.com/watch?v=HfGWVy-eMRc

Related

Parsing currency exchange data from https://uzmanpara.milliyet.com.tr/doviz-kurlari/

I prepare the program and I wrote this code with helping but the first 10 times it works then it gives me NULL values,
String url = "https://uzmanpara.milliyet.com.tr/doviz-kurlari/";
//Document doc = Jsoup.parse(url);
Document doc = null;
try {
doc = Jsoup.connect(url).timeout(6000).get();
} catch (IOException ex) {
Logger.getLogger(den3.class.getName()).log(Level.SEVERE, null, ex);
}
int i = 0;
String[] currencyStr = new String[11];
String[] buyStr = new String[11];
String[] sellStr = new String[11];
Elements elements = doc.select(".borsaMain > div:nth-child(2) > div:nth-child(1) > table.table-markets");
for (Element element : elements) {
Elements curreny = element.parent().select("td:nth-child(2)");
Elements buy = element.parent().select("td:nth-child(3)");
Elements sell = element.parent().select("td:nth-child(4)");
System.out.println(i);
currencyStr[i] = curreny.text();
buyStr[i] = buy.text();
sellStr[i] = sell.text();
System.out.println(String.format("%s [buy=%s, sell=%s]",
curreny.text(), buy.text(), sell.text()));
i++;
}
for(i = 0; i < 11; i++){
System.out.println("currency: " + currencyStr[i]);
System.out.println("buy: " + buyStr[i]);
System.out.println("sell: " + sellStr[i]);
}
here is the code, I guess it is a connection problem but I could not solve it I use Netbeans, Do I have to change the connection properties of Netbeans or should I have to add something more in the code
can you help me?
There's nothing wrong with the connection. Your query simply doesn't match the page structure.
Somewhere on your page, there's an element with class borsaMain, that has a direct child with class detL. And then somewhere in the descendants tree of detL, there is your table. You can write this as the following CSS element selector query:
.borsaMain > .detL table
There will be two tables in the result, but I suspect you are looking for the first one.
So basically, you want something like:
Element table = doc.selectFirst(".borsaMain > .detL table");
for (Element row : table.select("tr:has(td)")) {
// your existing loop code
}

convert XML to a custom Excel with Java

I need advise about how to convert XML to a custom Excel with Java
I need to convert XML to Excel with a custom layout. I found a POI and it seems like it can help with this task. But I don't have this experiences and as I understood POI works the best with in memory trees like DOM. I started to pars my XML(I can show a small part of, it's really big and goes deep)
<advantage>
<companies>
<name>Name1</name>
<name>Name2</name>
<name>Name3</name>
<name>Name4</name>
<name>Name6</name>
</companies>
<companyPreCode>
<PreCode>1</PreCode>
<PreCode>2</PreCode>
<PreCode>3</PreCode>
<PreCode>4</PreCode>
<PreCode>6</PreCode>
</companyPreCode>
by using DOM as I saw in one online tutorial like this
Document xmlDoc = getDocument("./src/xmlForTest.xml");
xmlDoc.getDocumentElement().normalize();
System.out.println("Root element of the doc is :\" "+ xmlDoc.getDocumentElement().getNodeName() + "\"");
NodeList listOfAdvantage = xmlDoc.getElementsByTagName("advantage"); //first we need to find total number of Advantage blocks
int totalAdvantage = listOfAdvantage.getLength();
System.out.println("Total no of advantage : " + totalAdvantage);
for (int s = 0; s < listOfAdvantage.getLength(); s++) //get into advantage
{
Node AdvantageNode = listOfAdvantage.item(s);
System.out.println("advantage number : " + s);
if (AdvantageNode.getNodeType() == Node.ELEMENT_NODE)
{
Element AdvantageElement = (Element) AdvantageNode;
NodeList CompanyList = AdvantageElement.getElementsByTagName("companies"); // find node companies
System.out.println("companies number : " + CompanyList.getLength());
for(int cl = 0; cl < CompanyList.getLength(); cl++) {
NodeList CompanyNameList = CompanyList.item(cl).getChildNodes(); //AdvantageElement.getElementsByTagName("name");
for (int j = 0; j < CompanyNameList.getLength(); j++) {
Node childNode = CompanyNameList.item(j);
if ("name".equals(childNode.getNodeName())) {
for (int nl = 0; nl < CompanyNameList.getLength(); nl++) {
Element CompanyNameElement = (Element) CompanyNameList.item(nl);
NodeList textFNList = CompanyNameElement.getChildNodes();
System.out.println("Company: " + nl + " :" + (textFNList.item(0)).getNodeValue().trim());
CompaniesNames.add((textFNList.item(0)).getNodeValue().trim());
}
}
}
}
}// end of if clause
}// end of for loop with s var
and now I have several questions
How to make this parsing easier? my file is big and in some places I Have the same tags for different things, like Name can be for company, product or a person. But it's getting hard to retrieve it one by one the way I did it
How to feed this data later into POI so I can start using this POI to build my Excel files? Because right now I have a set of ArrayLists with my data from different tags and I just don't know what I need to next with it

How to list items of a collection with Word Ole Automation

I'm using the SWT OLE api to edit a Word document in an Eclipse RCP. I read articles about how to read properties from the active document but now I'm facing a problem with collections like sections.
I would like to retrieve only the body section of my document but I don't know what to do with my sections object which is an IDispatch object. I read that the item method should be used but I don't understand how.
I found the solution so I'll share it with you :)
Here is a sample code to list all paragraphs of the active document of the word editor :
OleAutomation active = activeDocument.getAutomation();
if(active!=null){
int[] paragraphsId = getId(active, "Paragraphs");
if(paragraphsId.length > 0) {
Variant vParagraphs = active.getProperty(paragraphsId[0]);
if(vParagraphs != null){
OleAutomation paragraphs = vParagraphs.getAutomation();
if(paragraphs!=null){
int[] countId = getId(paragraphs, "Count");
if(countId.length > 0) {
Variant count = paragraphs.getProperty(countId[0]);
if(count!=null){
int numberOfParagraphs = count.getInt();
for(int i = 1 ; i <= numberOfParagraphs ; i++) {
Variant paragraph = paragraphs.invoke(0, new Variant[]{new Variant(i)});
if(paragraph!=null){
System.out.println("paragraph " + i + " added to list!");
listOfParagraphs.add(paragraph);
}
}
return listOfParagraphs;
}
}
}
}
}

Android - Reading XML issues

I've got an app that consumes a .NET web service which returns an XML string of data. I'm trying to read this XML and insert it into the local SQLite DB but I'm having some trouble. Here's a sample of the xml:
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="RemoteWebService"><OpenIssues> <Table> <IssueID>15351</IssueID> <IssueSummary>Computer keeps crashing. This continues to be a problem</IssueSummary> <LocationName>West Side</LocationName> <Status>WIP</Status> <CustomerID>89755</CustomerID> <CustomerName>West Side Computers</CustomerName> <CustomerShortName>WSC</CustomerShortName> <Notes /> <STATUS1>Work In Progress</STATUS1> <SubmittedBy>WSC - Tom Johns</SubmittedBy> <EQ_Replaced>true</EQ_Replaced></Table> </OpenIssues></string>
Using DOM, I'm trying to parse the results like so:
private void GetLatestData(String response) throws ParserConfigurationException, SAXException, IOException{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(response)));
//Normalize the document.
doc.getDocumentElement().normalize();
//Get Root Node.
NodeList nodeList = doc.getElementsByTagName("Table");
Node node = nodeList.item(0);
//Get Child Nodes.
for(int i = 0; i < node.getChildNodes().getLength(); i++){
IssueInfo issue = new IssueInfo();
Node tempNode = node.getChildNodes().item(i);
if(tempNode.getNodeName().equalsIgnoreCase("IssueID")){
issue.setIssueNumber(Long.parseLong(tempNode.getTextContent()));
}
if(tempNode.getNodeName().equalsIgnoreCase("IssueSummary")){
issue.setIssueNumber(Long.parseLong(tempNode.getTextContent()));
}
if(issue.getIssueNumber() > 0 && issue.getIssueSummary() != null){
creator = new IssueInfoCreator(this, DBVersion);
creator.open();
creator.InsertIssue(issue.getIssueNumber(), DateFormat.getDateInstance().format(new Date()), issue.getIssueSummary());
creator.close();
}
}
}
When I run it through the debugger, it gets "IssueID" just fine but how can I get it to pickup the next node "IssueSummary" right after that so I can insert the data at once? It seems like I need another loop somewhere, just not too sure where though.
If I understand your question correctly, this is what you may need to do.
Node node = nodeList.item(0);
Returns
<Table>
<IssueID>15351</IssueID>
<IssueSummary>Computer keeps crashing. This continues to be a problem</IssueSummary>
<Notes />
</Table>
node.getChildNodes().getLength();
Returns 3.
IssueInfo issue = new IssueInfo();
// Go through each child and find out node name and populate it.
for(int i = 0; i < node.getChildNodes().getLength(); i++){
Node tempNode = node.getChildNodes().item(i);
if(tempNode.getNodeName().equalsIgnoreCase("IssueID")){
issue.setIssueNumber(Long.parseLong(tempNode.getTextContent()));
}
if(tempNode.getNodeName().equalsIgnoreCase("IssueSummary")){
issue.setIssueNumber(Long.parseLong(tempNode.getTextContent()));
}
}
Move if logic out of the loop.
if(issue.getIssueNumber() > 0 && issue.getIssueSummary() != null){
creator = new IssueInfoCreator(this, DBVersion);
creator.open();
creator.InsertIssue(issue.getIssueNumber(), DateFormat.getDateInstance().format(new Date()), issue.getIssueSummary());
creator.close();
}
Seems like a simple DOM traversing issue.
If you can guarantee the next node is the summary, you could try using the getNextSibling() method for nodes
I modified your code so I could call it without using your classes. This is the code I used:
private static void GetLatestData(String response) {
try{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
/* the following 2 lines help you eliminate whitespace
from your xml DOM tree */
dbf.setValidating(true);
dbf.setIgnoringElementContentWhitespace(true);
DocumentBuilder db = dbf.newDocumentBuilder();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(response)));
//Normalize the document.
doc.getDocumentElement().normalize();
//Get Root Node.
NodeList nodeList = doc.getElementsByTagName("Table");
Node node = nodeList.item(0);
long issueNumber;
String summary;
//Get Child Nodes.
for(int i = 0; i < node.getChildNodes().getLength(); i++){
Node tempNode = node.getChildNodes().item(i);
if(tempNode.getNodeName().equalsIgnoreCase("IssueID")){
issueNumber = (Long.parseLong(tempNode.getTextContent()));
Node summaryNode = tempNode.getNextSibling();
summary = summaryNode.getTextContent();
System.out.println(String.format("Issue # %d, Summary: %s" , issueNumber,summary));
}
}
}catch(Exception exception){
exception.printStackTrace();
}
}
and I call it like this:
GetLatestData("<OpenIssues> " +
"<Table> " +
"<IssueID>15351</IssueID>" +
"<IssueSummary>Computer keeps crashing. This continues to be a problem</IssueSummary> " +
"<Notes />" +
"</Table></OpenIssues> ");
from a simple Java class. It's working all right for me, at least. It prints out:
Issue # 15351, Summary: Computer keeps crashing. This continues to be a problem
*smacks forehead*
issue will never have more than one value set, as it's created anew for each child node.
Just swap the two lines to create issue only once:
IssueInfo issue = new IssueInfo();
for(int i = 0; i < node.getChildNodes().getLength(); i++){
...
You should probably move the final if outside the for too, so it's not executed more than once.
AND you'll need to actually set the summary in the second if not. You're setting the 'issue number' twice.
Finally found the resolution to this with the help of my coworker and some digging around. It should be noted that we changed the WebService that returned a string from DataSet.GetXml() to an XmlDocument.InnerXml. This removed the spaces in between the nodes and then we were able to move forward from there. Here's the final code we used:
public void GetLatestData(SoapPrimitive xml)throws ParserConfigurationException, SAXException, IOException{
//get the factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc;
//parse using builder to get DOM representation of the XML file
InputSource is = new InputSource(new StringReader(xml.toString()));
doc = db.parse(is);
//Clear out Issues table first.
creator = new IssueInfoCreator(this, DBVersion);
creator.open();
creator.ClearIssueTable();
creator.close();
NodeList nodes = doc.getElementsByTagName("Table");
for(int i = 0; i < nodes.getLength(); i++) {
IssueInfo issue = new IssueInfo();
Element e = (Element)nodes.item(i);
issue.setIssueNumber(Long.parseLong(XMLfunctions.getValue(e, "IssueID")));
issue.setIssueSummary(XMLfunctions.getValue(e, "IssueSummary"));
issue.setDateReceived(DateFormat.format("MM/dd/yyyy hh:mm:ss", System.currentTimeMillis()).toString());
if(issue.getIssueNumber() > 0 && issue.getIssueSummary() != null){
creator = new IssueInfoCreator(this, DBVersion);
creator.open();
creator.InsertIssue(issue.getIssueNumber(), issue.getDateReceived(), issue.getIssueSummary());
creator.close();
}
}
}
And here is the getValue method of the XMLfuntions class:
public static String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return XMLfunctions.getElementValue(n.item(0));
}
public final static String getElementValue( Node elem ) {
Node kid;
if( elem != null){
if (elem.hasChildNodes()){
for( kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling() ){
if( kid.getNodeType() == Node.TEXT_NODE ){
return kid.getNodeValue();
}
}
}
}
return "";
}
Definately not taking credit for this, I found it here:
Programmer XR and modified it to my needs.
Hopefully this will help other people out!

Parsing xml string containing hyperlink

I am using DOM to parse an XML string as in the following example. This works great except in one instance. The document which I am trying to parse looks like this:
<response requestID=\"1234\">
<expectedValue>Alarm</expectedValue>
<recommendations>For steps on how to resolve visit Website and use the search features for \"Alarm\"<recommendations>
<setting>Active</setting>
<response>
The code I used to parse the XML is as follows:
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlResult));
Document doc = db.parse(is);
NodeList nlResponse = doc.getElementsByTagName("response");
String[] String = new String[3]; //result entries
for (int i = 0; i < nlResponse.getLength(); i++) {
Element e = (Element) nlResponse.item(i);
int c1 = 0; //count for string array
NodeList ev = e.getElementsByTagName("expectedValue");
Element line = (Element) ev.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
NodeList rec = e.getElementsByTagName("recommendations");
line = (Element) rec.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
NodeList set = e.getElementsByTagName("settings");
line = (Element) set.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
I am able to parse the code and put the result into a string array (as opposed to the System.out.println()). With the current code, my string array looks as follows:
String[0] = "Alarm"
String[1] = "For steps on how to resolve visit"
String[2] = "Active"
I would like some way of being able to read the rest of the information within "Recommendations" in order to ultimately display the hyperlink (along with other output) in a TextView. How can I do this?
I apologize for my previous answer in assuming your xml was ill-formed.
I think what is happening is that your call to the getCharacterDataFromElement is only looking at the first child node for text, when it will need to look at all the child nodes and getting the href attribute as well as the text for the 2nd child node when looking at the recommendations node.
e.g. after getting the Element for recommendation
String srec = "";
NodeList nl = line.getChildNodes();
srec += nl.item(0).getTextContent();
Node n = nl.item(1);
NamedNodeMap nm = n.getAttributes();
srec += "" + n.getTextContent() + "";
srec += nl.item(2).getTextContent();
String[c1] = srec;

Categories