<amount currency="USD">1000500</amount>
while parsing above string i am getting only attribute value .when i try to get node value null pointer exception
for getting node value using
NodeList amountList= estimateElement.getElementsByTagName("amount");
Element amtElement= (Element)amountList.item(0);
String amount=amtElement.getFirstChild().getnodevalue()
Thanks in advance
Aswan
Please try this. I assume that it is true:
NodeList list = estimateElement.getElementsByTagName("amount").item(0).getChildNodes();
Node node = (Node) list.item(0);
String value = node.getNodeValue();
Source : DOM parser
Element amtElement= (Element)amountList.item(0);
seems to be your element - so why are you calling getFirstChild()?
try this:
String amount=amtElement.getnodevalue()
have you checked out jdom? it has a nice documentation and is easy to use..
Try using the getTextContent() method:
NodeList amountList= estimateElement.getElementsByTagName("amount");
Element amtElement= (Element)amountList.item(0);
String amount=amtElement.getTextContent();
See here for more info.
Related
The input to the function this code is in, is a Node configNode. I need to extract the value of a child node inTemplate. The following is the code. Only null is printed.
XPath xpath = XPathFactory.newInstance().newXPath();
Node inTemplateNode = (Node) xpath.compile("#inTemplate").evaluate(configNode, XPathConstants.NODE);
String inTemplate = (inTemplateNode != null) ? inTemplateNode.getTextContent() : null;
System.out.println("inTemplate Value =" + inTemplate);
Can anyone help me as to why this code is not working.
The XPath expression #inTemplate selects the attribute named inTemplate of the context node (e.g. <config inTemplate="foo"/>). If you really need an attribute value then doing ((Element)configNode).getAttribute("inTemplate") should work in the DOM without the need to use any XPath.
If you want to select a child element (e.g. <config><inTemplate>foo</inTemplate></config>) named inTemplate then use the path inTemplate and not #inTemplate.
I know I can use DocumentBuilder to parse an xml file and traverse through the nodes but I am stuck at figuring out if the node has any more children. So for example in this xml:
<MyDoc>
<book>
<title> ABCD </title>
</book>
</MyDoc>
if I do node.hasChildNodes() I get true for both book and title. But what I am trying to do is if a node has some text value (not attributes) like title then print it otherwise don't do anything. I know this is some simple check but I just can't seem to find the answer on web. I am probably not searching with right keywords. Thanks in advance.
Try getChildNodes(). That will return a NodeList object which will allow you to iterate through all of the Nodes under the one you're referencing. regardless of what names they might have.
You have to check the type of the child nodes that you get by calling getChildNodes()by calling getNodeType(). <book> has a child of type ELEMENT_NODE whereas <title> has a child of type TEXT_NODE.
I am not sure but I think you wanted a way to iterate through all of the elements regardless of how nested it is. The below recursively goes through all elements. It then prints the elements value as long as its not just white space:
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("test.xml");
NodeList childNodes = doc.getChildNodes();
iterateNodes(childNodes);
}
private static void iterateNodes(NodeList childNodes)
{
for (int i = 0; i < childNodes.getLength(); ++i)
{
Node node = childNodes.item(i);
String text = node.getNodeValue();
if (text != null && !text.trim().isEmpty()) {
System.out.println(text);
}
if (node.hasChildNodes()) {
iterateNodes(node.getChildNodes());
}
}
}
Text nodes exist under element nodes in a DOM, and data is always stored in text nodes. Perhaps the most common error in DOM processing is to navigate to an element node and expect it to contain the data that is stored in that element. Not so! Even the simplest element node has a text node under it that contains the data.
Ref: http://docs.oracle.com/javase/tutorial/jaxp/dom/readingXML.html
I have this XML instance document:
<entities>
<person>James</person>
<person>Jack</person>
<person>Jim</person>
</entities>
And with the following code I iterate over the person nodes and print their names:
XPathExpression expr = xpath.compile("/entities/person");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodes.getLength() ; i++) {
Node node = nodes.item(i);
String nodeName = node.getNodeName();
String name = xpath.compile("text()").evaluate(node).trim();
System.out.printf("node type = %s, node name = %s\n", nodeName, name);
}
Now what I would like is to also have access to the index of each node.
I know I can trivially get it from the i loop variable but I want to get it as an XPath expression instead, preferably in no different way than I get the value of the text() XPath expression.
My use-case is that I am trying to handle all attributes I collect as XPath expressions (which I load at run-time from a config file) so that I minimize non-generic code, so I don't want to treat the index as a special case.
You'd have to use a trick like counting the preceding siblings
count(preceding-sibling::person)
which gives 0 for the first person, 1 for the second one, etc.
Try using position()
String index = xpath.compile("position()").evaluate(node).trim();
below i try to look for element and append a child to it ;but what the wrong with it!!??
// Document doc;
Element cust = doc.createElement("cust");
cust.appendChild(doc.createTextNode("anyname"));
org.w3c.dom.Node custmers = doc.getElementsByTagName("custmers").item(0);
custmers.appendChild(cust);
If you want to avoid navigating to the specific element, then try using xpath.
Link
I have a document org.w3c.dom.Document and i want to replace the value of a particular tag in xml.I have tried following but somehow it doesnot work.It doesnot give error but i cant see the change in value.
org.w3c.dom.Document
public boolean SetTextInTag(Document doc, String tag, String nodeValue)
{
Node node = getFirstNode(doc, tag);
if( node != null){
node.setNodeValue(nodeValue);
return true;
}
return false;
}
EG
<mytag> this value is to be changed </mytag>
I want the tag value to be chnaged to nodeValue.My code doesnot give any error but i cant see the change in value.
Try node.setTextContent(nodeValue) instead of node.setNodeValue(nodeValue).
Using setNodeValue on a node to change it's value will work, but only if it is a Text node. In all likelihood, the setNodeValue method was invoked on a Node that was not a text node. In reality, your code might be modifying an Element node, and therefore not having any result.
To explain this further, your document:
<mytag> this value is to be changed </mytag>
is actually seen by the parser as:
Element (name = mytag, value = null)
- TextNode (name = #text, value= " this value is to be changed ")
Element nodes will always have a value of null, so setting the value on them will not modify the value of the child text node. Using setTextContent as suggested in one of the answers will work, for it modifies the value of the TextNode instead of the Element.
You could also use setNodeValue to change the value, but only after detecting if the node is a TextNode:
if (node != null && node.getNodeType() == Node.TEXT_NODE) {
node.setNodeValue(nodeValue);
return true;
}
You need to write the xml-file out to see the changes. Do you do that?
The value of a node is not necessarily what you think it is. Take a look at the table here:
documentation
You might be better of using the replaceChild function for your purposes. That is
Node newChild = document.createTextNode("My new value");
Node oldChild = // Get the child you want to replace...
replaceChild(newChild, oldChild);
Remember, that what you are trying to replace is a text node that is the child of the tag you just looked up. So likely, Node oldChild = node.getFirstChild; is what you are looking for.
Look into this code... Might help you out.
<folks>
<person>
<name>Sam Spade</name>
<email>samspade#website.com</email>
</person>
<person>
<name>Sam Diamond</name>
<email>samdiamond#website.com</email>
</person>
<person>
<name>Sam Sonite</name>
<email>samsonite#website.com</email>
</person>
</folks>
Here is the code to parse and update the node value...
public void changeContent(Document doc,String newname,String newemail) {
Element root = doc.getDocumentElement();
NodeList rootlist = root.getChildNodes();
for(int i=0; i<rootlist.getLength(); i++) {
Element person = (Element)rootlist.item(i);
NodeList personlist = person.getChildNodes();
Element name = (Element)personlist.item(0);
NodeList namelist = name.getChildNodes();
Text nametext = (Text)namelist.item(0);
String oldname = nametext.getData();
if(oldname.equals(newname)) {
Element email = (Element)personlist.item(1);
NodeList emaillist = email.getChildNodes();
Text emailtext = (Text)emaillist.item(0);
emailtext.setData(newemail);
}
}
}