Couldn't able to read the attribute using DOM parser - java

i am having issues when reading the attribute of a link,
this is the structure of my xml,
<entry>
<updated>
<title>
<link href="">
</entry>
i managed to read the date and title correctly but the href attribute of the link is not working.
Here is my code,
NodeList nList = doc.getElementsByTagName("entry");
System.out.println("============================");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node node = nList.item(temp);
System.out.println(""); //Just a separator
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) node;
System.out.println("Date : " + eElement.getElementsByTagName("updated").item(0).getTextContent());
System.out.println("Title : " + eElement.getElementsByTagName("title").item(0).getTextContent());
// The below code is for reading href attribute of link,
NodeList node1 = eElement.getElementsByTagName("link");
Element eElement1 = (Element) node1;
System.out.println(eElement1.getAttribute("href"));
}
}
I am creating a new nodelist for the attributes of link but the code is not working.
error:
java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl cannot be cast to org.w3c.dom.Element
at Demo.main(Demo.java:45)

A NodeList is not an Element and cannot be cast to one (successfully), so this code isn't going to work:
NodeList node1 = eElement.getElementsByTagName("link");
Element eElement1 = (Element) node1;
A NodeList is, as the name suggests, a list of nodes (and in your case, the nodes will be Elements). So this code would work for the first link:
NodeList list = eElement.getElementsByTagName("link");
Element eElement1 = (Element) list.item(0);
...whereupon your getAttribute should work fine, as Element has getAttribute.
Side note: If your library has support for newer query functions, you could also do this:
String href = ((Element)eElement.querySelector("entry")).getAttribute("href");
...because querySelector returns just the first match (not a list) (or null if no matches; if that's a possibility, add a guard to the above). But I don't know how well querySelector is supported outside of browsers yet.

// The below code is for reading href attribute of link,
NodeList node1 = eElement.getElementsByTagName("link");
Element eElement1 = (Element) node1;
NodeList will give you Node object not Element, you can get href value as follows,
String hrefValue = nodeList.item(0).
getAttributes().getNamedItem("href").getNodeValue();

Related

xml update value using dom in java

I have to change the value that I find in the eElement that matches with the old value with another one.
I try with eElement.setAttribute(...) function and with setTextContent function but it doesn't work.
If we suppose that the new value is stored in a String variable called newValue, how can I make my code run?
NodeList leaf = doc.getElementsByTagName(relativeLeaf);
System.out.println(leaf.item(0).getNodeName());
for (int temp = 0; temp < leaf.getLength(); temp++) {
Node nNode = leaf.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
String oldValueInCells = eElement.getElementsByTagName(relativeLeaf).item(0).getTextContent();
System.out.println("old tag : " + eElement.getElementsByTagName(relativeLeaf).item(0).getTextContent());
if(oldValueInCells.contentEquals(oldVal)){
// ####
// here i have to change tha value in eElement
// where it match with the old Value with a new one
}
}
}
Basing on the documentation I think you can get the Node Element and then set a value. You first should get the node element like this:
Node node = eElement.getElementsByTagName(relativeLeaf).item(0); //You get the node here so you can use it as well to create OldValueInCells
String oldValueInCells = node.getTextContent();
System.out.println("old tag : " + oldValueInCells);
if(oldValueInCells.contentEquals(oldVal)){
// ####
// here i have to change tha value in eElement
// where it match with the old Value with a new one
node.setTextContent("new value"); //Here you will set the value to the node
}
Source: https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Node.html

Parse xml without tagname

I have a xml file
<Response>
<StatusCode>0</StatusCode>
<StatusDetail>OK</StatusDetail>
<AccountInfo>
<element1>value</element1>
<element2>value</element2>
<element3>value</element2>
<elementN>value</elementN>
</AccountInfo>
</Response>
And I want parse my elements in AccountInfo, but I dont know elements tag names.
Now Im using and have this code for tests, but in future I will recieve more elemenets in AccountInfo and I dont know how many or there names
String name="";
String balance="";
Node accountInfo = document.getElementsByTagName("AccountInfo").item(0);
if (accountInfo.getNodeType() == Node.ELEMENT_NODE){
Element accountInfoElement = (Element) accountInfo;
name = accountInfoElement.getElementsByTagName("Name").item(0).getTextContent();
balance = accountInfoElement.getElementsByTagName("Balance").item(0).getTextContent();
}
Heres 2 ways you can do it:
Node accountInfo = document.getElementsByTagName("AccountInfo").item(0);
NodeList children = accountInfo.getChildNodes();
or you can do
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList children = (NodeList) xPath.evaluate("//AccountInfo/*", document.getDocumentElement(), XPathConstants.NODESET);
Once you have your NodeList you can loop through them.
for(int i=0;i<children.getLength();i++) {
if(children.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element elem = (Element)children.item(i);
// If your document is namespace aware use localName
String localName = elem.getLocalName();
// Tag name returns the localName and the namespace prefix
String tagName= elem.getTagName();
// do stuff with the children
}
}

Retrieve node element's value based on attribute

How to retrieve node element's value based on attribute name using dom & xml parsing
<ROOT>
<A>
<aa name="xyz">k,l,m </aa>
<aa name="pqr">a,b,h </aa>
<aa name="abc">s,t,r </aa>
...
</A>
<B>
<bb name="t1">r,st,t</bb>
...
</B>
</ROOT>
...
Fragment of implementation tried:
NodeList nodeList = <xmlDoc>.getElementsByTagName("aa");
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element element = (Element) node;
System.out.println(element.getTextContent());
// ? getNodeValue() // ? how to get by passing attribute name as matching criteria,
// f.e : how to get a,b,h printed for node aa with attribute name as pqr
For attribute it will be : element.getAttribute("name");
If you want to search by attribute, then
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nl = (NodeList)xpath.compile("//aa[#name='pqr']").evaluate(doc, XPathConstants.NODESET);
//Rest of the code same
*Please change the xpath according to your need. I did not run it myself, but you get the idea.

Java XML with namespace issue

I have this code:
org.w3c.dom.Document doc = docBuilder.parse(representation.getStream());
Element element = doc.getDocumentElement();
NodeList nodeList = element.getElementsByTagName("xnat:MRSession.scan.file");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
// do something with the current element
my problem is with getElementsByTagName("xnat:MRSession.scan.file")
my xml looks like this:
<?xml version="1.0" encoding="UTF-8"?><xnat:MRSession "REMOVED DATA IGNORE">
<xnat:sharing>
<xnat:share label="23_MR1" project="BOGUS_GSU">
<!--hidden_fields[xnat_experimentData_share_id="1",sharing_share_xnat_experimentDa_id="xnat_E00001"]-->
</xnat:share>
</xnat:sharing>
<xnat:fields>
<xnat:field name="studyComments">
<!--hidden_fields[xnat_experimentData_field_id="1",fields_field_xnat_experimentDat_id="xnat_E00001"]-->S</xnat:field>
</xnat:fields>
<xnat:subject_ID>xnat_S00002</xnat:subject_ID>
<xnat:scanner manufacturer="GE MEDICAL SYSTEMS" model="GENESIS_SIGNA"/>
<xnat:prearchivePath>/home/ryan/xnat_data/prearchive/BOGUS_OUA/20120717_131900137/23_MR1</xnat:prearchivePath>
<xnat:scans>
<xnat:scan ID="1" UID="1.2.840.113654.2.45.2.108830" type="SAG LOCALIZER" xsi:type="xnat:mrScanData">
<!--hidden_fields[xnat_imageScanData_id="1"]-->
<xnat:image_session_ID>xnat_E00001</xnat:image_session_ID>
<xnat:quality>usable</xnat:quality>
<xnat:series_description>SAG LOCALIZER</xnat:series_description>
<xnat:scanner manufacturer="GE MEDICAL SYSTEMS" model="GENESIS_SIGNA"/>
<xnat:frames>29</xnat:frames>
<xnat:file URI="/home/ryan/xnat_data/archive/BOGUS_OUA/arc001/23_MR1/SCANS/1/DICOM/scan_1_catalog.xml" content="RAW" file_count="29" file_size="3968052" format="DICOM" label="DICOM" xsi:type="xnat:resourceCatalog">
So Basically I need to be able to iterate through all the xnat:MRSession/xnat:scan/xnat:file
elements and make some changes. Problem is
getElementsByTagName("xnat:MRSession.scan.file")
Is always null. Please help. Thanks
You could try the following using XPath:
Document document = // the parsed document
XPathFactory xPathFactory = XPathFactory.newInstance();
NodeList allFileNodes = xPathFactory.newXPath().evaluate("\\XNAT_NAMESPACE:file", document.getDocumentElement(), XPathConstants.NODESET);
Instead XNAT_NAMESPACE you would need to specify the exact namespace that is meant with the prefix "xnat" in your example.

How to navigate dom tree from XML in java

Below is a sample of the xml I am using, I have striped out some of the fields as they are unnecessary to demonstrate my point.
I am trying to parse the orders from this xml. However, I encounter a problem when I try to parse the product sets for each order. When the first order is processing, instead of adding the 2 sets detailed below, it will add all the sets it can find in the xml into the first order. I am not sure how to get around this as this is all quite new to me. Below is my java...
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
// Create a list of orders and sub elements
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
nList = doc.getElementsByTagName("order");
setList = doc.getElementsByTagName("set");
orders = new Order[nList.getLength()];
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
temp = new Order();
// Populate order with details from XML
parseClientDetails(eElement);
// Add sets
parseSets();
temp.setSets(setArray);
orders[i] = temp;
}
...
private void parseSets() {
Node nNode;
Element element;
for (int c = 0; c < setList.getLength(); c++) {
nNode = setList.item(c);
element = (Element) nNode;
tempSet = new Set();
tempSet.setBandwidth(getValue("bandwidth", element));
tempSet.setCategory(getValue("category", element));
tempSet.setSet_package(getValue("package", element));
setArray.add(tempSet);
}
}
XML:
<orderSet>
<order>
<customer name="SelectCustomerDetails">
<clientId>UK12345</clientId>
<etc>...</etc>
</customer>
<product>
<set>
<category>Silver</category>
<package>3000IP</package>
<bandwidth>160</bandwidth>
</set>
<set>
<category>Silver</category>
<package>3000IP</package>
<bandwidth>320</bandwidth>
</set>
</product>
</order>
<order>
...
</order>
</orderSet>
The problem is that you are calling doc.getElementsByTagName("set") which gives you a list of all sets in the entire document. Instead, you need to call it on each order, like this:
nList = doc.getElementsByTagName("order");
orders = new Order[nList.getLength()];
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
//get the sets for the current order only
NodeList setList = eElement.getElementsByTagName("set");
//now process the sets
}
You can use the 'javax.xml.xpath' APIs to get the content you need from the XML document. These APIs were introduced in Java SE 5 and provide much more control than 'getElementsByTagName'.
Example
What is best way to change one value in XML files in Java?

Categories

Resources