here is my code :
public void Login() {
try{
DocumentBuilderFactory builderfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = builderfactory.newDocumentBuilder();
File path = new File("src/dataPengguna/dataPengguna.xml");
Document doc = db.parse(path);
Element pengguna = (Element) doc.getElementsByTagName("pengguna");
NodeList list = pengguna.getElementsByTagName("user");
for (int i = 0; i < list.getLength(); i++) {
Element user = (Element) list.item(i);
Node username = user.getElementsByTagName("username").item(i);
Node password = user.getElementsByTagName("password").item(i);
if(loginuser.getText().equals(username.getTextContent())
&& loginpass.getText().equals(password.getTextContent())){
JOptionPane.showMessageDialog(rootPane, "welcome");
}
}
}catch(Exception e){
e.printStackTrace();
}
}
here is my xml :
<?xml version="1.0" encoding="UTF-8"?>
<pengguna>
<user>
<nama>septian</nama>
<username>septiansykes</username>
<password>1234</password>
<status>belumpinjam</status>
</user>
<user>
<nama>koko</nama>
<username>kokosan</username>
<password>12er</password>
<status>belumpinjam</status>
</user>
<user>
<nama>tamrin</nama>
<username>tamrincs</username>
<password>gt234</password>
<status>belumpinjam</status>
</user>
</pengguna>
and here is my error :
java.lang.ClassCastException:com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl cannot be cast to org.w3c.dom.Element
i try to get the element at the xml file, i want to check the element username and password, but there is an error about the cast class, it's seem difficult for me,... thanks before
This is the problem:
Element pengguna = (Element) doc.getElementsByTagName("pengguna");
getElementsByTagName doesn't return a single element - it returns multiple elements. You probably want something like:
NodeList penggunas = doc.getElementsByTagName("pengguna");
if (penggunas.getLength() != 1) {
// Handle this - e.g. throw an exception
}
Element pengguna = (Element) penggunas.item(0);
EDIT: Later, you've got a bug here:
Node username = user.getElementsByTagName("username").item(i);
Node password = user.getElementsByTagName("password").item(i);
This should be:
Node username = user.getElementsByTagName("username").item(0);
Node password = user.getElementsByTagName("password").item(0);
You're already within the user element - so you always want the first username and password elements within that element. Otherwise you're asking for the second username element within the second user element, the third username element within the third user element etc. The numbering is relevant to the element that you're in, not some global count.
getElementByTagName() returns a NodeList and you try to cast it to an Element. This line is incorrect and will give you the ClassCastException:
Element pengguna = (Element) doc.getElementsByTagName("pengguna");
Related
I am reading a dynamic XML file (without any known structure) and putting the relevant tag name and value to a hashmap (ex: metadata<tagName, Value> ).
My issue here is, I can not get the tagName but it only adds the root tagName and all the values of entire xml.
my XML is:
<?xml version="1.0" encoding="UTF-8"?>
<form kwf="VARA">
<sec1>
<docID>2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6</docID>
<qrCode>xx.jpg</qrCode>
<title>NOOO FORM NAME</title>
<ELO_VARAFNAME>NO</ELO_VARAFNAME>
<ELO_VARALNAME>NAME</ELO_VARALNAME>
<ELO_VARAEMAIL>noname#gmail.com</ELO_VARAEMAIL>
<ELO_VARAORBEONDOCID>2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6</ELO_VARAORBEONDOCID>
</sec1>
</form>
My Code is:
public static Map<String,String> getMetaDataFromOrbeonXML(File fXmlFile) throws SAXException, ParserConfigurationException, IOException
{
Map metaData = new HashMap();
String formName="";
String docID = "";
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("form");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
docID = eElement.getElementsByTagName("docID").item(0).getTextContent();
metaData.put("docID", docID);
metaData.put("appName", APP_NAME);
metaData.put(eElement.getTagName(), eElement.getTextContent());
System.out.println("META DATA MAP: "+ metaData.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return metaData;
}
And the out put is:
{form= 2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6
xx.jpg
NOOO FORM NAME
NO
NAME
noname#gmail.com
2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6
, docID=2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6, appName=VIRGINAUSI, formName=AITSLForm}
Tag names are missing in the map except the root element. Please help !
The code above correctly adds 2 entries in the map. The first entry, maps element Form to it's text content (which is the collection of the text content of all it's descendant nodes).
If you want to access the descendant nodes you'll need to use eElement.getChildNodes() and iterate over the NodeList returned.
This might be useful:
Java: Most efficient method to iterate over all elements in a org.w3c.dom.Document?
Im trying to extract data from a database using xml tags but I keeping getting this error
'java.lang.String org.w3c.dom.Node.getNodeValue()' on a null object reference
Not sure why its saying the tag is null when I have a log of the string before I try to extracts the data and it looks like it should I believe.
<?xml version="1.0" ?>
<database>
<account>
<id>1</id>
<fname>john</fname>
<lname>smith</lname>
<status>1</status>
</account>
</database>
That is the output from the string which I'm trying to extract the data from and here is the code I'm using to extract it.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();;
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse (new ByteArrayInputStream(s.getBytes()));
Element docEle = dom.getDocumentElement ();
NodeList nl = docEle.getElementsByTagName("account");
Element entry = (Element)nl.item(0);
Element id = (Element)entry.getElementsByTagName("id").item(0);
Element fname= (Element)entry.getElementsByTagName("fname").item(0);
Element lname = (Element)entry.getElementsByTagName("lname").item(0);
Element status= (Element)entry.getElementsByTagName("status").item(0);
user_id = id.getFirstChild().getNodeValue();
user_fname = fname.getFirstChild().getNodeValue();
user_lname = lname.getFirstChild().getNodeValue();
user_status = status.getFirstChild().getNodeValue();
The app crashes when it try's to get the node value from the first element, any help Is appreciated and thanks in advance
You have started the <account> tag but did not end it. Change </user> to </account>
Managed to figure it out, and this would be helpful for anyone with similar issues i hope.
to be able to read the tag names from an xml string I did the following (s is the xml string variable)
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(s));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();;
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(is);
Element docEle = dom.getDocumentElement ();
NodeList nl = docEle.getChildNodes();
if (nl != null) {
int length = nl.getLength();
for (int i = 0; i < length; i++) {
if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element el = (Element) nl.item(i);
if (el.getNodeName().contains("account")) {
user_id = el.getElementsByTagName("id").item(0).getTextContent();
user_fname = el.getElementsByTagName("fname").item(0).getTextContent();
user_lname = el.getElementsByTagName("lname").item(0).getTextContent();
user_status = el.getElementsByTagName("status").item(0).getTextContent();
}
}
}
}
the user_ variables have the xml tag values
I am not able to remove an element from root element. Below is the example of xml
<ADMIN-DATA>
<DATA-DECLARATION ID="Hi"> </DATA-DECLARATION>
<DATA ID="Hi">
<DATA-DECLARATION-REF ID-REF="Hi"> </DATA-DECLARATION-REF>
<DATA ID="Hi">
<DATA-DECLARATION ID="Delete"> </DATA-DECLARATION>
</DATA>
</DATA>
</ADMIN-DATA>
I want to delete
<DATA-DECLARATION ID="Delete"> </DATA-DECLARATION>
JDOM Code below
Element root = document.getRootElement();
String id = null;
boolean check = false;
String idRef = null;
ElementFilter filter = new org.jdom2.filter.ElementFilter(
"DATA-DECLARATION");
ElementFilter filter2 = new org.jdom2.filter.ElementFilter(
"DATA-DECLARATION-REF");
for (Element dataDecId : root.getDescendants(filter))
{
check = false;
id = dataDecId.getAttributeValue("ID");
for (Element dataDecIdRef : root.getDescendants(filter2))
{
idRef = dataDecIdRef.getAttributeValue("ID-REF");
if (null != idRef && idRef.equalsIgnoreCase(id))
{
check = true;
break;
}
}
if (!check)
{
root.removeContent(dataDecId);
}
}
Above root.removeContent(dataDecId); is not working. Correct me.
Note that <DATA-DECLARATION ID="Delete"> </DATA-DECLARATION> is not a child of the root element.... it's a child of a DATA element which in turn is a child of a DATA element which finally is a child of the ADMIN-DATA element.
You cannot ask the root element to remove DATA-DECLARATION ID="Delete" because it is not a direct child.
Note that the child itself knows it's location, so, the simpler way to do it, is to change root.removeContent(dataDecId) to be just dataDecId.detach()
Well, to me it looks like there are some errors in the .xml file. You're trying to get the ID-REF field whereas Delete only has an ID.
Moreover, I doubt that your XML file is correct considering you have a typo here:
<DATA-DECLARATION-REF ID-REF="Hi"> </ATA-DECLARATION-REF>
and two different tags here:
<DATA-DECLARATION ID="Delete"> </DATA-DECLARATION-REF>.
Another way:
XPATH combines tag and values in a clear way:
XPath xPath = XPathFactory.newInstance().newXPath();
String expression="//DATA-DECLARATION[#ID='Delete']"; // self-explained
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
for(int i=0; i<nodes.getLength(); i++)
{
Node the_node = nodes.item(i);
if(the_node instanceof Element)
{
Element the_element=(Element) the_node;
// FATHER
Node father=the_node.getParentNode();
// SUPPRESSION
father.removeChild(the_node);
// First one only ?
break;
}
}
I have a simple .xml file and need to parse it. The file is the following:
<table name="agents">
<row name="agent" password="pass" login="agent" ext_uid="133"/>
</table>
I need to get values of name, password, login, ext_uid to create a DB record.
What I have done for this:
created an or.w3c.dom.Document:
public Document getDocument(String fileName){
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setValidating(false);
DocumentBuilder builder = f.newDocumentBuilder();
return builder.parse(new File(fileName));
}
next I'm trying to print values:
document = getDocument(fileName);
NodeList nodes = document.getChildNodes();
for (int i=0; i<nodes.getLength(); i++){
Node node = nodes.item(i);
if(node.getNodeType() == Node.ELEMENT_NODE){
NodeList listofNodes = node.getChildNodes();
for(int j=0; j<listofNodes.getLength(); j++){
if(node.getNodeType() == Node.ELEMENT_NODE){
Node childNode = listofNodes.item(j);
System.out.println(childNode.getNodeValue()+" " + childNode.getNodeName());
}
}
}
}
I use this because I'm trying to find out how to get values: childNode.getNodeValue()+" " + childNode.getNodeName()
but the result is the following:
#text
null row
#text
in the first and te third cases the NodeValue is empty and in the second case it is null, that means, I guess that there no NodeValue at all.
So my question is how to get values of name, password, login, ext_uid?
childNode.getNodeValue() is obviously null as its an empty tag. You have to look for attributes
Node childNode = listofNodes.item(j);
Element e = (Element)childNode;
String name = e.getAttribute("name");
String password= e.getAttribute("password");
String login= e.getAttribute("login");
String ext_uid= e.getAttribute("ext_uid");
The <row> element has no value, it only has attributes. If it had a value it would look more like <row>this would be the value returned from getNodeValue()</row>.
One way to get the data is to iterate the XML node attributes, for example:
NamedNodeMap attrs = childNode.getAttributes();
if (attrs != null) {
for (int k = 0; k < attrs.getLength(); k++) {
System.out.println("Attribute: "
+ attrs.item(k).getNodeName() + " = "
+ attrs.item(k).getNodeValue());
}
}
The output of your code is showing #text due to the carriage returns (\n characters) in the example XML file, which, according the specification, should be preserved. The null in the example output is the empty node value from the value-less <row> element.
Use XPath instead:
XPath xp = XPathFactory.newInstance().newXPath();
System.out.println(xp.evaluate("/table/row/#name", doc));
System.out.println(xp.evaluate("/table/row/#password", doc));
System.out.println(xp.evaluate("/table/row/#login", doc));
System.out.println(xp.evaluate("/table/row/#ext_uid", doc));
I am having trouble parsing an xml file and retrieve data from it. Below is the xml and code snippet.
-----XML (test.xml)-----
<?xml version="1.0" encoding="utf-8"?>
<root>
<Server>
<IPAddress>xxx.xxx.xxx.xxx</IPAddress>
<UserName>admin</UserName>
<Password>admin</Password>
</Server>
-----Code Snippet: -----
public static String getInput(String element)
{
String value = "";
try {
File inputFile = new File("test.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbFactory.newDocumentBuilder();
Document inputData = builder.parse(inputFile);
inputData.getDocumentElement().normalize();
String[] elementArray = element.split("/");
XPath xPath = XPathFactory.newInstance().newXPath();
String xpathExpression = element;
System.out.println("Xpath Expression:" + xpathExpression);
NodeList node = (NodeList) xPath.compile(xpathExpression).evaluate(inputData, XPathConstants.NODESET);
System.out.println(node.getLength());
if (null != node){
System.out.println(node.getLength());
for (int i=0; i<node.getLength(); i++){
System.out.println(i);
System.out.println("Node count =" + node.getLength() + ";" +
"Node Name =" + node.item(i).getNodeName());
if (node.item(i).getNodeName() == elementArray[1]){
System.out.println(node.item(i).getNodeName()+ "=" + node.item(i).getNodeValue());
value = node.item(i).getNodeValue();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
The code compiles OK. While running, it just doesn't seem to find the nodes "Server" and it's child "IPAddress". The call to getInput() above would come from main in the format below:
getInput("Server/IPAddress");
Not sure where it's going wrong and I am really new to Xpath. I was wondering if someone can help.
Thanks!
The outermost element is <root/>, not <server/>. Your query needs to be
getInput("root/Server/IPAddress")
if you want to use the full path, or even
getInput("/root/Server/IPAddress")
to indicate you're starting at the root element. Alternatively, you could have XPath to search for all server elements all over the document:
getInput("//Server/IPAddress")
All of those will output
Xpath Expression:root/Server/IPAddress
1
1
0
Node count =1;Node Name =IPAddress
instead of
Xpath Expression:Server/IPAddress
0
0
You could somehow prepend one of the prefixes of your choice in the getInput() function, of course.