Link to home
Start Free TrialLog in
Avatar of trudyhlittle
trudyhlittleFlag for United States of America

asked on

Change parent element name to child text node value

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


Avatar of aozarov
aozarov

>>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);
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
Avatar of trudyhlittle

ASKER

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.
ASKER CERTIFIED SOLUTION
Avatar of aozarov
aozarov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
:-)