Rocket U2 | UniVerse & UniData

 View Only

 [Universe/XDOM api] How to insert an xml fragment from string into an existing DomHandle ?

Jump to Best Answer
Corentin Leblanc's profile image
Corentin Leblanc posted 06-22-2022 11:47

Hello,

Im using XDOM api in Universe 11.3.1 and I'm trying to import 'an xml fragment' from string into a current nodeHandle.

Explanations :

1 - Im creating an handle with XDOMOpen 
2 - Im appending a node into this handle
Example, at this time, my handle is a tree like this :
<root>
  <child>
  </child>
</root>

3 - Im using XDOMLocate to get a new handle to "child" node, nammed childNodeHandle.
4 - Now, I want to append to childNodeHandle an 'xml fragment' from a string (for example '<subChild><subSubChild><subSubSubChild></subSubSubChild></subSubChild></subChild>')

Problem : if I do a new XDOMOpen with this fragment and get a fragmentHandle, I cant use XDOMIAppend/XDOMInsert(childNodeHandle....fragmentHandle) because childNodeHandle and fragmentHandle are not in the same tree in memory - its normal (I got this error  : DOM Exception code: 4 (A node is used in a different document than the one that created it (that doesn't support it))

I cant use XDOMCreateNode either because XDOMCreateNode only allow to add ONE node, not a fragment.

=> I havent found a solution to insert this xml fragment into childNodeHandle without browsing recursively all nodes from fragmentHandle (and it is really really wordy...)

I think XDOM api is using java api like org.w3c.dom, or axis, xerces, who provides 'importNode' function but there is no implementation like XDOMImport.

Have you an idea for achieving this goal without browsing all nodes from fragment handle ?

Thanks for your help,
Corentin

Mike Rajkowski's profile image
ROCKETEER Mike Rajkowski Best Answer
Corentin,

Ok, I see the issue, if you have two XML documents, and want to add one as a child of the other, you will need to use the XDOMImportNode to get them both using the same XDOM.

i.e.
*
$INCLUDE UNIVERSE.INCLUDE XML.H
*
dupFlag = 0
xmlDocument = "<root><child></child></root>"
* Open the original XML
ST = XDOMOpen(xmlDocument, XML.FROM.STRING, domHandle); GOSUB CHECK_ST
* Navigate to where you want to insert the other xml
xpathString = "/root/child"; nsMap = ""
ST = XDOMLocate(domHandle, xpathString, nsMap, nodeHandle); GOSUB CHECK_ST
* Open the other XML
to_add = "<subChild><subSubChild><subSubSubChild>Stuff to add</subSubSubChild></subSubChild></subChild>"
ST = XDOMOpen(to_add, XML.FROM.STRING, xml_to_add); GOSUB CHECK_ST
* Navigate to the first element
other_path = "/subChild"
ST = XDOMLocate(xml_to_add, other_path, nsMap, newNodeHandle); GOSUB CHECK_ST
* Import the new XML into the XDOM of the original XML
ST = XDOMImportNode(nodeHandle, newNodeHandle, XDOM.TRUE, newHandle); GOSUB CHECK_ST
* Add the new XML to the original XML
ST = XDOMAddChild(nodeHandle, xpathString, nsMap, newHandle, dupFlag); GOSUB CHECK_ST
doc = ""
ST = XDOMWrite(domHandle, doc, XML.TO.STRING)
CRT doc
STOP
CHECK_ST:
IF ST = XML.SUCCESS THEN
CRT "OK"
END ELSE
CRT "ISSUE WITH LAST COMMAND"
ST = XMLGetError(errorCode, errorMessage)
CRT errorCode
CRT errorMessage
END
RETURN

> RUN BP FORUM
OK
OK
OK
OK
OK
OK
<?xml version="1.1" encoding="UTF-8" standalone="no" ?>
<root>

<child>
<subChild>
<subSubChild>
<subSubSubChild>Stuff to add</subSubSubChild>
</subSubChild>
</subChild>
</child>

</root>


Mike Rajkowski
Rocket Software
Corentin Leblanc's profile image
Corentin Leblanc
No one to help me?
Mike Rajkowski's profile image
ROCKETEER Mike Rajkowski
Sorry I did not answer sooner, but I am not 100% sure what you are trying to do.  

Here is a simple program that may help:
*
$INCLUDE UNIVERSE.INCLUDE XML.H
*
xmlDocument = "<root><child></child></root>"
ST = XDOMOpen(xmlDocument, XML.FROM.STRING, domHandle); GOSUB CHECK_ST
xpathString = "/root/child"; nsMap = ""
ST = XDOMLocate(domHandle, xpathString, nsMap, nodeHandle); GOSUB CHECK_ST
nodeName = "subChild"; nodeValue = ""; nodeType = XDOM.ELEMENT.NODE
ST = XDOMCreateNode(nodeHandle, nodeName, nodeValue, nodeType, newnodeHandle); GOSUB CHECK_ST
dupFlag = 0
ST = XDOMAddChild(nodeHandle, xpathString, nsMap, newnodeHandle, dupFlag); GOSUB CHECK_ST
doc = ""
ST = XDOMWrite(domHandle, doc, XML.TO.STRING)
CRT doc
STOP
CHECK_ST:
IF ST = XML.SUCCESS THEN
CRT "OK"
END ELSE
CRT "ISSUE WITH LAST COMMAND"
ST = XMLGetError(errorCode, errorMessage)
CRT errorCode
CRT errorMessage
END
RETURN

>RUN BP FORUM
OK
OK
OK
OK
<?xml version="1.1" encoding="UTF-8" standalone="no" ?>
<root>

<child>
<subChild/>
</child>

</root>

Mike Rajkowski
Rocket Software
Corentin Leblanc's profile image
Corentin Leblanc
Thank you for your reply Mike

Your solution is ok for adding ONE node nammed 'subChild' into ​'child' node with XDOMCreateNode/XDOMAddChild instructions. I know that, for adding one node into another.

But, I'm not trying to insert just one node, but I want to insert a big xml fragment from string, with many nodes : instead of inserting a node like 'subChild', I want to insert a fragment from string like '<subChild><subSubChild><subSubSubChild>... ... ... ...</subSubSubChild></subSubChild></subChild>'

In other words, I have a domHandle, and I want to insert a big xml string fragment inside.

Corentin

Corentin Leblanc's profile image
Corentin Leblanc
Great Mike, thank you !

This is exactly what I was looking for, but XDOMImportNode is not describe in our documentation :)
In which version of Universe was this method added?

Regards,
Corentin


Attachment  View in library
image.png 132 KB