aspose file tools*
The moose likes XML and Related Technologies and the fly likes Inserting a new node from scratch Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » XML and Related Technologies
Bookmark "Inserting a new node from scratch" Watch "Inserting a new node from scratch" New topic
Author

Inserting a new node from scratch

Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
I have a piece of code which parses an XML file via the DOM DocumentBuilderFactory/DocumentBuilder/Document classes. Now I need to insert an XML node which can be at any random level in the XML file. I have a string containing what the name of that element should be, but how do I insert that into my xml document? I can't seem to figure it out without throwing: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted

Note:
I have an XML file called "x" open:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document x = db.parse(new File(path));

I am inside of a loop with a Node type currently set at the node I need to insert a child under (loopNode), and I have an array container with the string of what the new XML element needs to be named inside of loopNode (element[i]).

I am trying to do some variation of:

Element newNode = x.createElement(element[i]);
loopNode.appendChild(newNode);

But like I said, cannot get around that "HIERARCHY_REQUEST_ERR".

Any thoughts? My apologies if this is redundant or if my verbiage is incorrect or confusing. I took like one java class many years ago and haven't worked with a ton of OOP since then.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18657
    
    8

Perhaps you're trying to add your new Element node as a child of, say, a Text node? Or as the second child of the Document, which is supposed to have a single Element as its only child?

I think that posting a small but complete code example might help to illustrate your problem.
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Thank you kind sir.

Hopefully this isn't too ugly. I know it's inefficient but it'll save me literally days of time spent manipulating XML files.

Long story short, I have a delimited XML path which I split up into the elements[] array. I search each level in the XML file for the corresponding node from the elements[] array. So at any point I may reach a point where I haven't encountered the node, and thus need to create it.

I am hoping the situation is pretty straight-forward.....I have a DOM and a node saved from that DOM, and I need to append a node below that level (a child of "loopNode").

Please see the obnoxious comments starting with "!!!NOTE!!!":
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Formatting is ugly....BAH HUMBUG!

I've also tried w/out the usage of importNode method. I'm guessing it has to do with how I'm initializing my "newNode" element.

I'm also GUESSING that I just need two little lines of code which I'm having a hard time mentally arriving at - first line being the initialization of the node named after the string in elements[j], the second line being in append/insert beneath the "loopNode" element.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18657
    
    8

Ripley Rubio wrote:Formatting is ugly....BAH HUMBUG!


Formatting is much nicer if you use the "code" tags to format your code instead of the "quote" tags.

I've also tried w/out the usage of importNode method. I'm guessing it has to do with how I'm initializing my "newNode" element.

I'm also GUESSING that I just need two little lines of code which I'm having a hard time mentally arriving at - first line being the initialization of the node named after the string in elements[j], the second line being in append/insert beneath the "loopNode" element.


Regardless of my suggestion that your problem had something to do with the type of node you were adding to, rather than the node you were adding? I'm going to suggest that again.
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Paul Clapham wrote:Regardless of my suggestion that your problem had something to do with the type of node you were adding to, rather than the node you were adding? I'm going to suggest that again.

My fault, first post here, I glossed over the code tag.

I did not ignore your suggestion, just need to contemplate it. This is the first time I've done heavy parsing of XML and like I said, the first time in many years I've been back in Java.

The format of the XML is typically done for organization. For example:

The pertinent XML chunk for the file I'm parsing might be:



And my period-delimited string might be something like "general.display.boolean1".

The code will loop and find "general", move on to search for and find "display", move on to search for "boolean1" and NOT find it. Thus I would need to append/insert "boolean1" as a child of "display".

Does this help refine the advice you give? I was able to append under the root - is there a reason why I cannot append under a deeper node?
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12806
    
    5
Thus I would need to append/insert "boolean1" as a child of "display".


Are you trying to insert an Element named boolean1 having some Text Node child - or what?

What are you expecting the resulting XML chunk to look like when you are done?

Bill
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18657
    
    8

Ripley Rubio wrote:I was able to append under the root - is there a reason why I cannot append under a deeper node?


Like I said, it depends on what the deeper node is. You can't append a node under a Text node, for example. That's why I suggested you should look at the node you're trying to insert under, not at the node you're trying to insert.

You might contemplate using something like

to test that.
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
William Brogden wrote:
Thus I would need to append/insert "boolean1" as a child of "display".


Are you trying to insert an Element named boolean1 having some Text Node child - or what?

What are you expecting the resulting XML chunk to look like when you are done?

Bill

If the original XML is this:



I have an XML path in a delimited string of varied length, and a value. The path dynamically gets appended until the final node, at which point it will set the value of the node.

For instance, if I have:
XML path= "general.display.misc.boolean1"
Value= "true"

The XML would look like this after processing:



So if it's not the final node in the string delimited list, it just needs to insert the tags. If it's the last one, it then needs to set the value.

The 2 things I need to figure out how to do to to complete my code:
1) Insert/append child start and end tags when at a Node at Xth level in the xml file (e.g. insert <misc></misc> under <display>)
2) Set the value for the final Node (e.g. <boolean1>true</boolean1> under <misc>)

Hopefully I'm in the ballpark and am not way off on my terminology.

Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Paul Clapham wrote:
Ripley Rubio wrote:I was able to append under the root - is there a reason why I cannot append under a deeper node?


Like I said, it depends on what the deeper node is. You can't append a node under a Text node, for example. That's why I suggested you should look at the node you're trying to insert under, not at the node you're trying to insert.

You might contemplate using something like

to test that.

Thank you, I will play with this and see if it helps me get somewhere.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12806
    
    5
1) Insert/append child start and end tags when at a Node at Xth level in the xml file (e.g. insert <misc></misc> under <display>)
2) Set the value for the final Node (e.g. <boolean1>true</boolean1> under <misc>)


1. is an Element named misc - you don't mess with "stat and end tags" - an Element node handles that
2. the text "true" is a Node of type Text that is the child of the boolean1 Element

You really need to get familiar with the standard library org.w3c.dom package - the table and method list in the Node JavaDocs for example

Bill

Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Paul Clapham wrote:
You might contemplate using something like

to test that.

This outputs false.

As you can see by my source code, I used a NodeList to loop children of each level of the XML file. And now I am in a situation where I have a Node from the NodeList and I need to append a child nodes and ultimately set a value on the last node. Did I enter a programmatic black hole by taking this approach, or is there some sort of work-around I can find to salvage my code? e.g. cast my node (loopNode) as an element or something, and then append my new node?

Pardon my ignorance, kind people. Java isn't my forte...YET.

I am studying the Node javadoc in the meantime.
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
I should have been appending my new node to "node", not "loopNode". It turns out loopNode was garbage text that was being looped over that must be between tags ("#text"). That was one of my problems, onto the next one!

It's no longer erroring but I am not seeing my tag show up after the childAppend.
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Here is a more granular explanation of my issue, see the comments in the code explaining next steps. I have a Node object I need to append to, and an array of strings which need to become the children tag(s).



Thoughts? Is this possible? Straight-forward?
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
I think I'm cooking with gas now.

Finally saw some results on this little chunk of code.
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
Many pitfalls for java beginners....

New issue:

setNodeValue does not appear to be working for me. It is null both before and after. I saw some buzz about this happening while googling, but none of the solutions have been applicable to my case (yet).

Trying to set a Node to "true".



Output is:

Setting booleanX=true
Before- null
After- null
true
true
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12806
    
    5
If you will refer to the table in org.w3c.dom.Node javadocs that I pointed you to previously, you will see that:

Element Nodes have a null nodeValue - duh!

The only kind of Nodes with a non-null value are Attr, CDATASection, Comment and Text nodes.

Thats what we have been trying to tell you,

XML <thing>value</thing> is an Element node named "thing" with a Text node child which has the value "value".

Bill
Ripley Rubio
Greenhorn

Joined: Jun 18, 2012
Posts: 12
William Brogden wrote:If you will refer to the table in org.w3c.dom.Node javadocs that I pointed you to previously, you will see that:

Element Nodes have a null nodeValue - duh!

The only kind of Nodes with a non-null value are Attr, CDATASection, Comment and Text nodes.

Thats what we have been trying to tell you,

XML <thing>value</thing> is an Element node named "thing" with a Text node child which has the value "value".

Bill

Ah, thank you. The light bulb went off on that explanation. Now that I see your previous explanation I am not sure how I didn't pick up on that. Thanks for you patience.
 
Don't get me started about those stupid light bulbs.
 
subject: Inserting a new node from scratch