
Anyway, here's my solution, in case anybody uses it and runs into the same problem I had.
It's not a perfect solutions since GetXMLNodeText() returns all the text within the given node, without regard to its position in relation to child nodes (i.e. in moving <p>This<b>will</b>not<b>work</b></p> to another location you will get <p><b>will</b><b>work</b>Thisnot</p>.) There's no easy way to get around this without resorting to the expat API, which is beyond me.
It's great for configuration files though, where you just need to maintain the DOM structure and nodes which contain data have only one child (the actual text.)
Code: Select all
Prototype.l ProtoMvXMLNode(*node, *par, *prv=0)
Prototype.l ProtoCpXMLNode(*node, *par, *prv=0)
Procedure.l XMLDeepCopy(*node, *dest)
If *node = 0 Or *dest = 0
ProcedureReturn 0
EndIf
nodeType = XMLNodeType(*node)
If nodeType = #PB_XML_Normal Or nodeType = #PB_XML_Instruction
nodeName.s = GetXMLNodeName(*node)
If nodeType = #PB_XML_Instruction And nodeName <> ""
SetXMLNodeName(*dest, nodeName)
Else
SetXMLNodeName(*dest, nodeName)
EndIf
EndIf
If nodeType <> #PB_XML_Root
nodeText.s = GetXMLNodeText(*node)
SetXMLNodeText(*dest, nodeText)
EndIf
If nodeType = #PB_XML_Normal And ExamineXMLAttributes(*node)
Repeat
hasAttr = NextXMLAttribute(*node)
If hasAttr <> 0
attr.s = XMLAttributeName(*node)
value.s = XMLAttributeValue(*node)
SetXMLAttribute(*dest, attr, value)
EndIf
Until hasAttr = 0
EndIf
*child = ChildXMLNode(*node)
If *child = 0
ProcedureReturn 1
EndIf
NewList Nodes.l()
; Otherwise add the next children.
Repeat
AddElement(Nodes())
Nodes() = *child
*child = NextXMLNode(*child)
Until *child = 0
*new = 0
*par = *dest
*prv = 0
ForEach Nodes()
nodeType = XMLNodeType(Nodes())
If nodeType = #PB_XML_Root
ProcedureReturn 0
EndIf
If *prv = 0
*new = CreateXMLNode(*par, 0, nodeType)
If *new = 0
ProcedureReturn 0
EndIf
Else
*new = CreateXMLNode(*par, *prv, nodeType)
If *new = 0
ProcedureReturn 0
EndIf
EndIf
If XMLDeepCopy(Nodes(), *new) = 0
ProcedureReturn 0
EndIf
*prv = *new
Next
ProcedureReturn 1
EndProcedure
Procedure.l ProcCpXMLNode(*node, *par, *prv)
If *par = 0 Or *node = 0
ProcedureReturn 0
EndIf
*new = 0
nodeType = XMLNodeType(*node)
If nodeType = #PB_XML_Root
ProcedureReturn 0
EndIf
If *prv = 0
*new = CreateXMLNode(*par, 0, nodeType)
If *new = 0
ProcedureReturn 0
EndIf
Else
*new = CreateXMLNode(*par, *prv, nodeType)
If *new = 0
ProcedureReturn 0
EndIf
EndIf
ProcedureReturn XMLDeepCopy(*node, *new)
EndProcedure
Procedure.l ProcMvXMLNode(*node, *par, *prv)
ret.l = ProcCpXMLNode(*node, *par, *prv)
If ret > 0
DeleteXMLNode(*node)
EndIf
ProcedureReturn ret
EndProcedure
CpXMLNode.ProtoCpXMLNode = @ProcCpXMLNode()
MvXMLNode.ProtoMvXMLNode = @ProcMvXMLNode()