Attaching Node with null value to a DOM document - java

I am trying to attach a node to a DOM document in the example code shown below.
1)I initialized the nodes "title, type" to null.
2)I tried to append these above nodes to the Document "child_doc" and then tried to set a new value to these nodes.
But on doing the above, I am getting a java.lang.NullPointerException at this line:
child_doc.appendChild(title).setNodeValue("New" + childType);
How do I resolve this?
Thanks,
Sony
Example code:
public synchronized void attachNodeToParent1 (Element parent, String childType) throws ParserConfigurationException {
Document parent_doc = parent.getOwnerDocument();
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document child_doc = docBuilder.newDocument();
Element child = null;
Node title = null;
Node type = null;
child_doc.appendChild(title).setTextContent("New" + childType);
child_doc.appendChild(type).setTextContent(childType);
child = child_doc.getDocumentElement();
parent.appendChild(child);
}

Initialize them to proper elements:
Element title = child_doc.createElement("type");
Element type = child_doc.createElement("title);

Related

How to get data from XML node?

I am struggling to get the data out of the following XML node. I use DocumentBuilder to parse XML and I usually get the value of a node by defining the node but in this case I am not sure how the node would be.
<Session.openRs status="success" sessionID="19217B84:AA3649FE:B211FF37:E61A78F1:7A35D91D:48E90C41" roleBasedSecurity="1" entityID="1" />
This is how I am getting the values for other tags by the tag name.
public List<NYProgramTO> getNYPPAData() throws Exception {
this.getConfiguration();
List<NYProgramTO> to = dao.getLatestNYData();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = null;
// Returns chunkSize
/*List<NYProgramTO> myList = getNextChunk(to);
ExecutorService executor = Executors.newFixedThreadPool(myList.size());
myList.stream().parallel()
.forEach((NYProgramTO nyTo) ->
{
executor.execute(new NYExecutorThread(nyTo, migrationConfig , appContext, dao));
});
executor.shutdown();
executor.awaitTermination(300, TimeUnit.SECONDS);
System.gc();*/
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource source = new InputSource();
for(NYProgramTO nyProgram: to) {
String reqXML = nyProgram.getRequestXML();
String response = RatingRequestProcessor.postRequestToDC(reqXML, URL);
// dao.storeData(nyProgram);
System.out.println(response);
if(response != null) {
source.setCharacterStream(new StringReader(response));
document = builder.parse(source);
NodeList list = document.getElementsByTagName(NYPG3Constants.SERVER);
for(int iterate = 0; iterate < list.getLength(); iterate++){
Node node = list.item(iterate);
if(node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
nyProgram.setResponseXML(response);
nyProgram.setFirstName(element.getElementsByTagName(NYPG3Constants.F_NAME).item(0).getTextContent());
nyProgram.setLastName(element.getElementsByTagName(NYPG3Constants.L_NAME).item(0).getTextContent());
nyProgram.setPolicyNumber(element.getElementsByTagName(NYPG3Constants.P_NUMBER).item(0).getTextContent());
nyProgram.setZipCode(element.getElementsByTagName(NYPG3Constants.Z_CODE).item(0).getTextContent());
nyProgram.setDateOfBirth(element.getElementsByTagName(NYPG3Constants.DOB).item(0).getTextContent());
nyProgram.setAgencyCode(element.getElementsByTagName(NYPG3Constants.AGENCY_CODE).item(0).getTextContent());
nyProgram.setLob(element.getElementsByTagName(NYPG3Constants.LINE_OF_BUSINESS).item(0).getTextContent());
if(element.getElementsByTagName(NYPG3Constants.SUBMISSION_NUMBER).item(0) != null){
nyProgram.setSubmissionNumber(element.getElementsByTagName(NYPG3Constants.SUBMISSION_NUMBER).item(0).getTextContent());
} else {
nyProgram.setSubmissionNumber("null");
}
I need to get the value for sessionId. What I want to know is the node, I am sure it can't be .I am retrieving the values via tag names so what would be the tag name in this case?
Thanks in advance
You should consider using XPath. At least for me, is so much easy to use and, in your case, in order to get sessionID you could try something like this:
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/Session.openRs/#sessionID";
String sessionID = xPath.evaluate(expression,document);
You can obtain 'document' like this:
Document document = builder.newDocumentBuilder();
Hope this can help!!

Casting JDom 1.1.3 Element to Document without DocumentBuilderFactory or DocumentBuilder

I need to find the easier and the efficient way to convert a JDOM element (with all it's tailoring nodes) to a Document. ownerDocument( ) won't work as this is version JDOM 1.
Moreover, org.jdom.IllegalAddException: The Content already has an existing parent "root" exception occurs when using the following code.
DocumentBuilderFactory dbFac = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFac.newDocumentBuilder();
Document doc = null;
Element elementInfo = getElementFromDB();
doc = new Document(elementInfo);
XMLOutputter xmlOutput = new XMLOutputter();
byte[] byteInfo= xmlOutput.outputString(elementInfo).getBytes("UTF-8");
String stringInfo = new String(byteInfo);
doc = dBuilder.parse(stringInfo);
I think you have to use the following method of the element.
Document doc = <element>.getDocument();
Refer the API documentation It says
Return this parent's owning document or null if the branch containing this parent is currently not attached to a document.
JDOM content can only have one parent at a time, and you have to detatch it from one parent before you can attach it to another. This code:
Document doc = null;
Element elementInfo = getElementFromDB();
doc = new Document(elementInfo);
if that code is failing, it is because the getElementFromDB() method is returning an Element that is part of some other structure. You need to 'detach' it:
Element elementInfo = getElementFromDB();
elementInfo.detach();
Document doc = new Document(elementInfo);
OK, that solves the IllegalAddException
On the other hand, if you just want to get the document node containing the element, JDOM 1.1.3 allows you to do that with getDocument:
Document doc = elementInfo.getDocument();
Note that the doc may be null.
To get the top most element available, try:
Element top = elementInfo;
while (top.getParentElement() != null) {
top = top.getParentElement();
}
In your case, your elementInfo you get from the DB is a child of an element called 'root', something like:
<root>
<elementInfo> ........ </elementInfo>
</root>
That is why you get the message you do, with the word "root" in it:
The Content already has an existing parent "root"

Delete TextContents of XML element before appending text

I am appending text to XML element iteratively like the following
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new FileInputStream(new File("./myXML.xml")));
Element element = doc.getDocumentElement();
NodeList node1 = doc.getElementsByTagName("name");
Element fn= (Element) node1.item(0);
Text text = doc.createTextNode(Content);
fn.appendChild(text);
printtoXML(doc);
My printXML method is updating xml by using TransformerFactory
fn.setTextContent() method does not work here,Because in every iteration it setting old text to new text.
I want to append Text iteratively, and in my next execution i want to delete old text contents of the particular element and append it again.
I have to execute the program many times for my testing and i don't want to append the same text again and again....
Could you please help me to solve this problem..
this might work
Text text;
void callsomefunctionthousendtimes(){
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new FileInputStream(new File("./myXML.xml")));
text = doc.createTextNode("");
Element element = doc.getDocumentElement();
NodeList node1 = doc.getElementsByTagName("name");
Element fn= (Element) node1.item(0);
//TODO call your functionName(content) 1000 times here
fn.appendChild(text);
printtoXML(doc);
}
void functionName(String content){
text = text.replaceWholeText(text.getWholeText() + content);
}
added bonusus, only load the doc in once

How to get XML node by ID and NamedNodeMap - Java DOM XML

I have an xml file with messages:
<bus>
<message id="58afdb36-9080-4dd8-922e-ee516b2b5073">
<retrievedDate>Mon Feb 18 14:43:23 GMT 2013</retrievedDate>
<addedDate>Mon Feb 18 14:43:23 GMT 2013</addedDate>
<state>initialised</state>
<content>content placeholder</content>
</message>
</bus>
I am creating a method to change the state of a message for a given ID.
However I keep getting NullPointerException when I try to get the node with the ID I want. Have tried experimenting with getElementById and getElementsByTagName, but I always get null instead of the node I want.
public static int updateMessageState(UUID messageID, String newState)
throws ParserConfigurationException,
SAXException, IOException, TransformerException {
String filepath = "data.xml";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
// Get Message
Node message = doc.getElementById(messageID.toString());
// Find and update the state
NamedNodeMap atrMap = message.getAttributes();
Node nodeAtr = atrMap.getNamedItem("state");
nodeAtr.setTextContent(newState);
// Save write to XML
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
return 0;
}
When using getElementById() you must make sure that the type of the attribute "id" is ID or else null will be returned from the method. See here.
I don't see an example of how you are using getElementsByTagName(String str) so I will provide an example. When using getElementsByTagName() you will actually get a NodeList corresponding to the elements which have the tag. In your example you would use doc.getElementsByName("message") in order to retrieve a node list of the message elements. You can then use the node list to then find what you are looking for.
You can get Id using Element:
// Get the main element by tag name
Node bus = doc.getElementsByTagName("bus").item(0);
//get a NodeList
NodeList list = bus.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
System.out.println("\nCurrent Element :" + node.getNodeName());
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) node;
System.out.println(" id : " + eElement.getAttribute("id"));
}
}

Getting value of child node from XML in java

My xml file looks like this
<InNetworkCostSharing>
<FamilyAnnualDeductibleAmount>
<Amount>6000</Amount>
</FamilyAnnualDeductibleAmount>
<IndividualAnnualDeductibleAmount>
<NotApplicable>Not Applicable</NotApplicable>
</IndividualAnnualDeductibleAmount>
<PCPCopayAmount>
<CoveredAmount>0</CoveredAmount>
</PCPCopayAmount>
<CoinsuranceRate>
<CoveredPercent>0</CoveredPercent>
</CoinsuranceRate>
<FamilyAnnualOOPLimitAmount>
<Amount>6000</Amount>
</FamilyAnnualOOPLimitAmount>
<IndividualAnnualOOPLimitAmount>
<NotApplicable>Not Applicable</NotApplicable>
</IndividualAnnualOOPLimitAmount>
</InNetworkCostSharing>
I am trying to get Amount value from <FamilyAnnualDeductibleAmount> and also from <FamilyAnnualOOPLimitAmount>. How do i get those values in java?
You may use two XPath queries /InNetworkCostSharing/FamilyAnnualDeductibleAmount and InNetworkCostSharing/FamilyAnnualOOPLimitAmount or just get the node InNetworkCostSharing and retrieve the values of its two direct children.
Solution using XPath:
// load the XML as String into a DOM Document object
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
ByteArrayInputStream bis = new ByteArrayInputStream("YOUR XML".getBytes());
Document doc = docBuilder.parse(bis);
// XPath to retrieve the content of the <FamilyAnnualDeductibleAmount> tag
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("/InNetworkCostSharing/FamilyAnnualDeductibleAmount/text()");
String familyAnnualDeductibleAmount = (String)expr.evaluate(doc, XPathConstants.STRING);
StAX based solution:
XMLInputFactory f = XMLInputFactory.newInstance();
XMLStreamReader rdr = f.createXMLStreamReader(new FileReader("test.xml"));
while (rdr.hasNext()) {
if (rdr.next() == XMLStreamConstants.START_ELEMENT) {
if (rdr.getLocalName().equals("FamilyAnnualDeductibleAmount")) {
rdr.nextTag();
int familyAnnualDeductibleAmount = Integer.parseInt(rdr.getElementText());
System.out.println("familyAnnualDeductibleAmount = " + familyAnnualDeductibleAmount);
} else if (rdr.getLocalName().equals("FamilyAnnualOOPLimitAmount")) {
rdr.nextTag();
int familyAnnualOOPLimitAmount = Integer.parseInt(rdr.getElementText());
System.out.println("FamilyAnnualOOPLimitAmount = " + familyAnnualOOPLimitAmount);
}
}
}
rdr.close();
Note that StAX is especially good for cases like yours, it skips all unnecessary elements reading only the ones you need
Try something like this(use getElementsByTagName to get the parent nodes and then get the value be reaching out to child node):
File xmlFile = new File("NetworkCost.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile );
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("FamilyAnnualDeductibleAmount");
String familyDedAmount = nList.item(0).getChildNodes().item(0).getTextContent();
nList = doc.getElementsByTagName("FamilyAnnualOOPLimitAmount");
String familyAnnualAmount =
nList.item(0).getChildNodes().item(0).getTextContent();
I think I found the solution with this question from stackoverflow
Getting XML Node text value with Java DOM

Categories

Resources