trudyhlittle
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< /BusinessP artnerID>
<SentDate>2005-04-15</Sent Date>
<SentTime>03:08:30</SentTi me>
<TransactionCount>2</Trans actionCoun t>
</HEADER>
<EVENT>
<Account>F04000178</Accoun t>
<EVENT_TYPE>PROBATE</EVENT _TYPE>
<Date>15-Apr-2005 00:00:00</Date>
</EVENT>
<EVENT>
<Account>F04000178</Accoun t>
<EVENT_TYPE>AUDIT</EVENT_T YPE>
<Date>15-Apr-2005 00:00:00</Date>
</EVENT>
</TRANSACTION>
I have the following path: /TRANSACTION/EVENT/EVENT_T YPE
I need my resulting document to look like this:
TRANSACTION>
<HEADER>
<BusinessPartnerID>ABCDDD< /BusinessP artnerID>
<SentDate>2005-04-15</Sent Date>
<SentTime>03:08:30</SentTi me>
<TransactionCount>2</Trans actionCoun t>
</HEADER>
<PROBATE>
<Account>F04000178</Accoun t>
<Date>15-Apr-2005 00:00:00</Date>
</PROBATE>
<AUDIT>
<Account>F04000178</Accoun t>
<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
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<
<SentDate>2005-04-15</Sent
<SentTime>03:08:30</SentTi
<TransactionCount>2</Trans
</HEADER>
<EVENT>
<Account>F04000178</Accoun
<EVENT_TYPE>PROBATE</EVENT
<Date>15-Apr-2005 00:00:00</Date>
</EVENT>
<EVENT>
<Account>F04000178</Accoun
<EVENT_TYPE>AUDIT</EVENT_T
<Date>15-Apr-2005 00:00:00</Date>
</EVENT>
</TRANSACTION>
I have the following path: /TRANSACTION/EVENT/EVENT_T
I need my resulting document to look like this:
TRANSACTION>
<HEADER>
<BusinessPartnerID>ABCDDD<
<SentDate>2005-04-15</Sent
<SentTime>03:08:30</SentTi
<TransactionCount>2</Trans
</HEADER>
<PROBATE>
<Account>F04000178</Accoun
<Date>15-Apr-2005 00:00:00</Date>
</PROBATE>
<AUDIT>
<Account>F04000178</Accoun
<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
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
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
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().remov eChild(nod e);
}
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 </Business PartnerID>
<SentDate>2005-04-18</Sent Date>
<SentTime>11:38:01</SentTi me>
<TransactionCount>3</Trans actionCoun t>
</HEADER>
<EVENT>
<EVENT_TYPE>PROBATE</EVENT _TYPE>
</EVENT>
<EVENT>
<EVENT_TYPE>AUD</EVENT_TYP E>
</EVENT>
<PROBATE>
<Account>F04000178</Accoun t>
<Date>2005-04-18</Date>
</PROBATE>
<AUD>
<Account>F04000178</Accoun t>
<Date>2005-04-18</Date>
</AUD>
</TRANSACTION>
After I call the function my XML looks like this:
<TRANSACTION>
<HEADER>
<BusinessPartnerID>ECEVARR </Business PartnerID>
<SentDate>2005-04-18</Sent Date>
<SentTime>11:38:01</SentTi me>
<TransactionCount>3</Trans actionCoun t>
</HEADER>
<EVENT>
<EVENT_TYPE>AUD</EVENT_TYP E>
</EVENT>
<PROBATE>
<Account>F04000178</Accoun t>
<Date>2005-04-18</Date>
</PROBATE>
<AUD>
<Account>F04000178</Accoun t>
<Date>2005-04-18</Date>
</AUD>
</TRANSACTION>
Thanks.
public static void removeAll(Node node, short nodeType, String name) {
if (node.getNodeType() == nodeType &&
(name == null || node.getNodeName().equals(
node.getParentNode().remov
}
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
<SentDate>2005-04-18</Sent
<SentTime>11:38:01</SentTi
<TransactionCount>3</Trans
</HEADER>
<EVENT>
<EVENT_TYPE>PROBATE</EVENT
</EVENT>
<EVENT>
<EVENT_TYPE>AUD</EVENT_TYP
</EVENT>
<PROBATE>
<Account>F04000178</Accoun
<Date>2005-04-18</Date>
</PROBATE>
<AUD>
<Account>F04000178</Accoun
<Date>2005-04-18</Date>
</AUD>
</TRANSACTION>
After I call the function my XML looks like this:
<TRANSACTION>
<HEADER>
<BusinessPartnerID>ECEVARR
<SentDate>2005-04-18</Sent
<SentTime>11:38:01</SentTi
<TransactionCount>3</Trans
</HEADER>
<EVENT>
<EVENT_TYPE>AUD</EVENT_TYP
</EVENT>
<PROBATE>
<Account>F04000178</Accoun
<Date>2005-04-18</Date>
</PROBATE>
<AUD>
<Account>F04000178</Accoun
<Date>2005-04-18</Date>
</AUD>
</TRANSACTION>
Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
:-)
I don't think you can. just create a new element vi doc.createElement("new_ele
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);