I am using XML.jl.
I have a basic XML node that I use as a base from which I wish to construct many slightly different instances. On each occasion, I want to copy the basic node and build from there. The Readme page for XML.jl says:
Node
is an immutable type. However, you can easily create a copy with one or more field values changed by using theNode(::Node; kw...)
constructor wherekw
are the fields you want to change.
I donβt want to change any fields, So I just tried new_node=XML.Node(old_node)
.
I then build up the rest of the new_node
as I want it.
The consequence of this is that the changes I make to new_node
also propagate back to old_node
- specfically to its child nodes.
I have experimented with many different ways of specifying the kw...
options in XML.Node
but to no avail. For example, I tried variations on new_node=XML.Node(old_node, children=[x for x in XML.children(old_node)])
to try to copy the child nodes, too.
Two ways I have found to make this work are to try deepcopy(old_node)
and XML.parse(Node, XML.write(old_node))[1]
.
The first of these seems not to be recommended (βA brief conversation of deepcopy
vs copy
in Julia and why deepcopy
should be avoided unless you know you have a good reason to use it (serialization-like)β (here)).
The second is very inefficient.
MWE below the fold
using XML
copynode(o)=Node(o)
deepcopynode(o) = deepcopy(o)
parsenode(o) = XML.parse(Node, XML.write(o))[1]
function createRule()
rule = XML.Element("x14:cfRule", type="iconSet", priority="1", id="XXXX-xxxx-XXXX")
icon = XML.Element("x14:iconSet", iconSet="3Arrows", custom="1")
cfvo = XML.Element("x14:cfvo", type="percent")
push!(cfvo, XML.Element("xm:f", XML.Text("0")))
push!(icon, cfvo)
push!(rule, icon)
return rule
end
function createCfx(rule, f)
cfx=f(rule)
cfvo = XML.Element("x14:cfvo", type="percent")
push!(cfvo, XML.Element("xm:f", XML.Text("dummy")))
push!(cfx[1], f(cfvo))
push!(cfx[1], f(cfvo))
push!(cfx[1], f(cfvo))
cfx[1]["iconSet"] = "4Arrows"
return cfx
end
println("\nusing XML.Node()")
rule = createRule()
println("\n `rule` before:\n",XML.write(rule))
cfx=createCfx(rule, copynode)
println("\n `cfx`:\n",XML.write(cfx))
println("\n `rule` after:\n",XML.write(rule))
println("\nusing deepcopy()")
rule = createRule()
println("\n `rule` before:\n",XML.write(rule))
cfx=createCfx(rule, deepcopynode)
println("\n `cfx`:\n",XML.write(cfx))
println("\n `rule` after:\n",XML.write(rule))
println("\nusing XML.parse()")
rule = createRule()
println("\n `rule` before:\n",XML.write(rule))
cfx=createCfx(rule, parsenode)
println("\n `cfx`:\n",XML.write(cfx))
println("\n `rule` after:\n",XML.write(rule))
using XML.Node()
`rule` before:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="3Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
`cfx`:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="4Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
`rule` after:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="4Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
using deepcopy()
`rule` before:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="3Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
`cfx`:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="4Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
`rule` after:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="3Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
using XML.parse()
`rule` before:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="3Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
`cfx`:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="4Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
<x14:cfvo type="percent">
<xm:f>dummy</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
`rule` after:
<x14:cfRule type="iconSet" priority="1" id="XXXX-xxxx-XXXX">
<x14:iconSet iconSet="3Arrows" custom="1">
<x14:cfvo type="percent">
<xm:f>0</xm:f>
</x14:cfvo>
</x14:iconSet>
</x14:cfRule>
Does anyone have any suggestions?