0

Here is the XML file snippet that gives some currencies. All of them has values like "currency name", "forex buying", "forex selling" etc...

<?xml version="1.0" encoding="UTF-8"?>

<Currency CrossOrder="1" Kod="AUD" CurrencyCode="AUD">
        <Unit>1</Unit>
        <Isim>AVUSTRALYA DOLARI</Isim>
        <CurrencyName>AUSTRALIAN DOLLAR</CurrencyName>
        <ForexBuying>4.4233</ForexBuying>
        <ForexSelling>4.4521</ForexSelling>
        <BanknoteBuying>4.4030</BanknoteBuying>
        <BanknoteSelling>4.4789</BanknoteSelling>
        <CrossRateUSD>1.3839</CrossRateUSD>
        <CrossRateOther/>
    </Currency>

<Currency CrossOrder="2" Kod="DKK" CurrencyCode="DKK">
        <Unit>1</Unit>
        <Isim>DANIMARKA KRONU</Isim>
        <CurrencyName>DANISH KRONE</CurrencyName>
        <ForexBuying>0.93070</ForexBuying>
        <ForexSelling>0.93527</ForexSelling>
        <BanknoteBuying>0.93004</BanknoteBuying>
        <BanknoteSelling>0.93742</BanknoteSelling>
        <CrossRateUSD>6.5827</CrossRateUSD>
        <CrossRateOther/>
    </Currency>

And here is my actual code:

import javax.lang.model.element.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class PasteClass {

    public static void main(String[] args) {

        try {
            File xmlFile = new File("TCMB2.xml");
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            org.w3c.dom.Document document = documentBuilder.parse(xmlFile);
            NodeList list = document.getElementsByTagName("Currency");

            for (int i = 0; i < list.getLength(); i++) {

                Node node = list.item(i);

                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    System.out.println("Kod: "
                            + ((org.w3c.dom.Document) element)
                                .getElementsByTagName("Kod").item(0).getTextContent());
                    System.out.println("Para Birimi: "
                            + ((org.w3c.dom.Document) element)
                                .getElementsByTagName("Isim").item(0).getTextContent());
                    System.out.println("Forex Satis Ucreti: " 
                            + ((org.w3c.dom.Document) element)
                                .getElementsByTagName("ForexSelling").item(0).getTextContent());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

What I want to do is, simply grabbing some data from an XML file. This is my first work with XML. I just want it to print "kod", "Isim" and "forex Selling" values for each element. But when I run the code, I get this error:

java.lang.ClassCastException: java.xml/com.sun.org.apache.xerces.internal.dom.DeferredElementImpl cannot be cast to java.compiler/javax.lang.model.element.Element at javaPaket.WONTWORK.main(WONTWORK.java:36)

(36th line is the "Element element = (Element) node;" line btw. )

How can I fix that? I copied the similar code from the other site and just changed the values. Yet I got this error.....

Erik
  • 503
  • 1
  • 7
  • 26
blackwater7
  • 107
  • 1
  • 9
  • may be use should have look at this https://stackoverflow.com/questions/13296583/java-xml-classcastexception-deferredtextimpl – soorapadman Aug 16 '18 at 12:58
  • Already looked there but couldn't understand the solution properly...Since my code is different than hims :/ – blackwater7 Aug 16 '18 at 13:01
  • Check my code, it goes off from your example and gives you the ability to parse the document correctly. The values you want to print seem odd as they are in different places in the XML elements **(i.e. "kod", "Isim" and "forex Selling"**), but my example does provide you with every value you are looking for. – ViaTech Aug 16 '18 at 14:53
  • Kod="AUD" is a attirubute of Currency tag. So you must use 'getAttribute' instade of 'getTag'. – theMind Aug 17 '18 at 07:08

4 Answers4

2

Would you try to run below code? Only the code in the for block was changed.

public static void main(String[] args) {

    try {

        File xmlFile = new File("TCMB2.xml");
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        org.w3c.dom.Document doc = documentBuilder.parse(xmlFile);

        NodeList list = doc.getElementsByTagName("Currency");


        for (int i = 0; i < list.getLength(); i++) {

            Node node = list.item(i);

            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) node;
                System.out.println("Kod: " + element.getAttribute("Kod"));
                System.out.println("Para Birimi: " + element.getElementsByTagName("Isim").item(0).getTextContent());
                System.out.println("Forex Satis Ucreti: " + element.getElementsByTagName("ForexSelling").item(0).getTextContent()) ;

            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Sample Output:

Kod: AUD
Para Birimi: AVUSTRALYA DOLARI
Forex Satis Ucreti: 4.4521
Kod: DKK
Para Birimi: DANIMARKA KRONU
Forex Satis Ucreti: 0.93527

  • Thanks it worked. So it seems like the problem is inserting "((org.w3c.dom.Document)" to "element"s. Its suggested by the eclipse IDE itself but its totally unnecessary lol – blackwater7 Aug 17 '18 at 07:29
1

The Issue is that your imports are not correct

import javax.lang.model.element.Element;

is not the same as

import org.w3c.dom.Element;

That is causing conflicts in your java Code. try with this Imports:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

Make a simple example and is working.


Try to clean and build it again your code.

Worst case scenarios try with this

  org.w3c.dom.Element element = (org.w3c.dom.Element) node;
Gatusko
  • 2,503
  • 1
  • 17
  • 25
  • I removed all my imports and then putted yours there. Still not working. When I run the code it says: "java.lang.ClassCastException: java.xml/com.sun.org.apache.xerces.internal.dom.DeferredElementImpl cannot be cast to java.xml/org.w3c.dom.Document at javaPaket.WONTWORK.main(WONTWORK.java:36)" – blackwater7 Aug 16 '18 at 13:54
0

I think you should do:

Element element = (org.w3c.dom.Element) node;

Because you are also importing javax.lang.model.element.Element, and I suspect that the casting is occurring with that type (as the stacktrace itself implies).

Andrea
  • 6,032
  • 2
  • 28
  • 55
  • Didn't work. When I edit my code like you mentioned, it says me to cast it just like I posted in my thread. And when I do it I got an runtime error lol. – blackwater7 Aug 16 '18 at 13:20
0

Okay you had a few issues with your code involving imports which people have already brought up, but you had a few other changes that needed to be implemented to your code for it to work the way it looks like you want.

First here is the XML I am using, you did not have a root element which messed up your code, but you did say it wasn't the full file you were using so I was not sure if you needed to see it.

Test.xml:

<root>
    <Currency CrossOrder="1" Kod="AUD" CurrencyCode="AUD">
            <Unit>1</Unit>
            <Isim>AVUSTRALYA DOLARI</Isim>
            <CurrencyName>AUSTRALIAN DOLLAR</CurrencyName>
            <ForexBuying>4.4233</ForexBuying>
            <ForexSelling>4.4521</ForexSelling>
            <BanknoteBuying>4.4030</BanknoteBuying>
            <BanknoteSelling>4.4789</BanknoteSelling>
            <CrossRateUSD>1.3839</CrossRateUSD>
            <CrossRateOther/>
    </Currency>

    <Currency CrossOrder="2" Kod="DKK" CurrencyCode="DKK">
            <Unit>1</Unit>
            <Isim>DANIMARKA KRONU</Isim>
            <CurrencyName>DANISH KRONE</CurrencyName>
            <ForexBuying>0.93070</ForexBuying>
            <ForexSelling>0.93527</ForexSelling>
            <BanknoteBuying>0.93004</BanknoteBuying>
            <BanknoteSelling>0.93742</BanknoteSelling>
            <CrossRateUSD>6.5827</CrossRateUSD>
            <CrossRateOther/>
    </Currency>
</root>

And here is the Java that parses your XML:

    import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.HashMap;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Test{

    public static void main(String[] args) {

         /* 
        These are the values for the xml lines based on your file
        Unit            = 1
        Isim            = 2
        CurrencyName    = 3 
        ForexBuying     = 4
        ForexSelling    = 5
        BanknoteBuying  = 6
        BanknoteSelling = 7
        CrossRateUSD    = 8
         */

        //create a HashMap to map the loop count to the proper name
        //while printing, these are based on numbers commented above
        HashMap<Integer, String> mapOfItems = new HashMap<>();
        mapOfItems.put(1, "Unit");
        mapOfItems.put(2, "Isim");
        mapOfItems.put(3, "CurrencyName");
        mapOfItems.put(4, "ForexBuying");
        mapOfItems.put(5, "ForexSelling");
        mapOfItems.put(6, "BanknoteBuying");
        mapOfItems.put(7, "BanknoteSelling");
        mapOfItems.put(8, "CrossRateUSD");  

        try {
            File xmlFile = new File("test.xml");
            DocumentBuilderFactory documentBuilderFactory = 
                    DocumentBuilderFactory.newInstance();

            DocumentBuilder documentBuilder =  
                    documentBuilderFactory.newDocumentBuilder();

            org.w3c.dom.Document document = 
                    documentBuilder.parse(xmlFile);

            NodeList list = document.getElementsByTagName("Currency");

            for(int i=0;i<list.getLength();i++) {

                Node node = list.item(i);

                if(node.getNodeType() == Node.ELEMENT_NODE) {

                    //gather node with specific attribute, here item(2) == Kod 
                    String kodValue = node.getAttributes().item(2).getTextContent();

                    //create array based on text content, split be new line    
                    String[] values = node.getTextContent().split("\n");

                        System.out.println("\nKOD = "+ kodValue);
                        for (Integer e = 0; e < values.length; e++) {

                            //replaceAll() is for regex replacement of white space here
                            values[e] = values[e].replaceAll(
                                    "^\\s+|\\s+$|\\s*(\n)\\s*|(\\s)\\s*", "$1$2")
                                     .replace("\t"," ");

                            //just check to make sure null isn't being printed
                            if(mapOfItems.get(e)!= null)
                                System.out.println(mapOfItems.get(e)+" = "+values[e]);
                        }
                    }
                }
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}
ViaTech
  • 2,143
  • 1
  • 16
  • 51
  • I haven't tried this code yet but even if its working, this code has some subjects that I don't know about Java. The examples I found in google & youtube doesn't use any map or X.value method. Their codes are just like my post here. Can't it be simplier? – blackwater7 Aug 17 '18 at 05:17
  • Hey, I just realised I used a wrong value in my thread. I don't need the "Kod" value in my result. Since its an "attribute", I don't care about that. But I need to access some of the/or maybe all elements in the code. (ie. ForexBuying, CurrencyName, Isim, Unit....) So, is there any simplier version of the code now? Thanks in advance. – blackwater7 Aug 17 '18 at 05:35
  • @blackwater7, what you are asking for is already provided in my code, and I would give you a more concise example but you did already accept an answer and my version does already work based on your question so I'm not seeing a benefit to changing anything unless you still need help. I used HashMap because it is a nearly perfect Java Data Type for mapping loop counts to the "element" names. – ViaTech Aug 17 '18 at 11:39