[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Change parent element name to child text node value

Posted on 2005-04-15
6
Medium Priority
?
231 Views
Last Modified: 2010-03-31
Hi,

I have an XML document I am traversing using the Document Object Model (DOM).  The code needs to process any number of different xml formats so I will never know what the incoming XML document looks like.  I have a path to an element which I need to use it's text node value to replace it's parent element name.  I can get a reference to the child element, and it's text node value using it's path and to the parent using the getParent() function.  I cannot however figure out how to change the name of the parent element.  Also, once I change the parent element name, I need to remove the child from the parent.

Here is an example document:
<TRANSACTION>
    <HEADER>
        <BusinessPartnerID>ABCDDD</BusinessPartnerID>
        <SentDate>2005-04-15</SentDate>
        <SentTime>03:08:30</SentTime>
        <TransactionCount>2</TransactionCount>
    </HEADER>
    <EVENT>
        <Account>F04000178</Account>
        <EVENT_TYPE>PROBATE</EVENT_TYPE>
        <Date>15-Apr-2005 00:00:00</Date>
    </EVENT>
    <EVENT>
        <Account>F04000178</Account>
        <EVENT_TYPE>AUDIT</EVENT_TYPE>
        <Date>15-Apr-2005 00:00:00</Date>
    </EVENT>
</TRANSACTION>

I have the following path: /TRANSACTION/EVENT/EVENT_TYPE

I need my resulting document to look like this:
TRANSACTION>
    <HEADER>
        <BusinessPartnerID>ABCDDD</BusinessPartnerID>
        <SentDate>2005-04-15</SentDate>
        <SentTime>03:08:30</SentTime>
        <TransactionCount>2</TransactionCount>
    </HEADER>
    <PROBATE>
        <Account>F04000178</Account>
        <Date>15-Apr-2005 00:00:00</Date>
    </PROBATE>
    <AUDIT>
        <Account>F04000178</Account>
        <Date>15-Apr-2005 00:00:00</Date>
    </AUDIT>
</TRANSACTION>

I realize I could use XSL to transform the document, however, since I have no idea what the incoming document looks like (only the path of the element to use to modify it's parent name), I would have to generate the XSL dynamically, which I'm thinking would be even more difficult.

Thanks


0
Comment
Question by:trudyhlittle
  • 4
  • 2
6 Comments
 
LVL 15

Expert Comment

by:aozarov
ID: 13795803
>>I cannot however figure out how to change the name of the parent element.
I don't think you can. just create a new element  vi doc.createElement("new_element_name");
add the children of the old element to the new element via getChildNodes() and appendChild (inside iteration)
and remove the old element via removeChild(element);
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13795808
For examples look at: http://javaalmanac.com/cgi-bin/search/find.pl?words=DOM
In your case you only care about two classes Document (to create new element) and Node.
http://java.sun.com/j2se/1.4.2/docs/api/org/w3c/dom/Node.html
0
 

Author Comment

by:trudyhlittle
ID: 13808395
Thanks, I've got the new element added and all the children moved to the new parent.  I am now having difficulty removing the old elements.  I am using one of the examples you provided a link to, but only one of my elements is being removed.  I am using the removeAll method:

 public static void removeAll(Node node, short nodeType, String name) {
    if (node.getNodeType() == nodeType &&
        (name == null || node.getNodeName().equals(name))) {
      node.getParentNode().removeChild(node);
    }
    else {
      // Visit the children
      NodeList list = node.getChildNodes();
      for (int i = 0; i < list.getLength(); i++) {
        removeAll(list.item(i), nodeType, name);
      }
    }
  }

I am calling: removeAll(pXML, Node.ELEMENT_NODE, vParentNodeName) where pXML is the document bellow, and vParentNodeName is "EVENT".

<TRANSACTION>
    <HEADER>
        <BusinessPartnerID>ECEVARR</BusinessPartnerID>
        <SentDate>2005-04-18</SentDate>
        <SentTime>11:38:01</SentTime>
        <TransactionCount>3</TransactionCount>
    </HEADER>
    <EVENT>
        <EVENT_TYPE>PROBATE</EVENT_TYPE>
    </EVENT>
    <EVENT>
        <EVENT_TYPE>AUD</EVENT_TYPE>
    </EVENT>
    <PROBATE>
        <Account>F04000178</Account>
        <Date>2005-04-18</Date>
    </PROBATE>
    <AUD>
        <Account>F04000178</Account>
        <Date>2005-04-18</Date>
    </AUD>
</TRANSACTION>

After I call the function my XML looks like this:

<TRANSACTION>
    <HEADER>
        <BusinessPartnerID>ECEVARR</BusinessPartnerID>
        <SentDate>2005-04-18</SentDate>
        <SentTime>11:38:01</SentTime>
        <TransactionCount>3</TransactionCount>
    </HEADER>
    <EVENT>
        <EVENT_TYPE>AUD</EVENT_TYPE>
    </EVENT>
    <PROBATE>
        <Account>F04000178</Account>
        <Date>2005-04-18</Date>
    </PROBATE>
    <AUD>
        <Account>F04000178</Account>
        <Date>2005-04-18</Date>
    </AUD>
</TRANSACTION>

Thanks.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 15

Accepted Solution

by:
aozarov earned 1000 total points
ID: 13808539
That is probably because NodeList is a a "live list" and when you remove child it will effect its length and the get item by index.

Try this instead:
Pass to removeAll a Set -> Set toRemove =  new HashSet();
removeAll(toRemove, pXML, Node.ELEMENT_NODE, vParentNodeName) ;
// And then do this
for (Iterator i = toRemove.iterator(); i.hasNext(); )
{
Node node = (Node) i.next();
node.getParentNode().removeChild(node);
}      


public static void removeAll(Set toRemove, Node node, short nodeType, String name) {
    if (node.getNodeType() == nodeType &&
        (name == null || node.getNodeName().equals(name))) {
             toRemove.add(node);
    }
    else {
      // Visit the children
      NodeList list = node.getChildNodes();
      for (int i = 0; i < list.getLength(); i++) {
        removeAll(list.item(i), nodeType, name);
      }
    }
  }
0
 

Author Comment

by:trudyhlittle
ID: 13809075
Yep, that worked.  I had to make a slight correction to your example.  You forgot to include the toRemove set in the recursive call back to removeAll.  Thanks, a bunch.  I really appreciate the help.
0
 
LVL 15

Expert Comment

by:aozarov
ID: 13809082
:-)
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses
Course of the Month19 days, 15 hours left to enroll

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question