I have some xml files where I want to insert the contents of one xml file into another. I thought I'd use LastChild and the InsertAfter method to accomplish this. So far it's not working for me.
Here is the parent.xml file:
<manifest>
<manifestExecution>
<assetDetail>
<fileAsset fileAssetGuid="parentguid1">
<parentfile1 />
</fileAsset>
<fileAsset fileAssetGuid="parentguid2">
<parentfile2 />
</fileAsset>
</assetDetail>
</manifestExecution>
</manifest>
And here is the child.xml file:
<manifest>
<manifestExecution>
<assetDetail>
<fileAsset fileAssetGuid="childguid1">
<childfile1 />
</fileAsset>
</assetDetail>
</manifestExecution>
</manifest>
What I want to do is select the fileAsset node(s) from child.xml and insert into parent.xml after the last fileAsset node in parent.xml.
Here is my test code:
$parent = [xml] (Get-Content d:\temp\parent.xml)
$parentnode = $parent.manifest.manifestExecution.assetDetail
$child = [xml] (Get-Content d:\temp\child.xml)
$childnode = $child.manifest.manifestExecution.assetDetail.InnerXml
$parentnode.InsertAfter($childnode, $parentnode.LastChild)
Here is the error msg I'm getting:
Cannot convert argument "0", with value: "<fileAsset fileAssetGuid="childguid1"> <childfile1 /></fileAsset>", for "InsertAfter" to type "System.Xml.XmlNode": "Cannot conver
t the "<fileAsset fileAssetGuid="childguid1"><childfile1 /></fileAsset>" value of type "System.String" to type "System.Xml.XmlNode"."
At line:5 char:24
+ $parentnode.InsertAfter <<<< ($childnode, $parentnode.LastChild)
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
What am I doing wrong?
You need to iterate through $childnode
's children, remove them from their parent, and import them into the new document context ($child
and $parent
are different XmlDocument
instances) before appending to $parentnode
.
This will append all fileAsset
nodes from $childnode
into $parentnode
.
$parent = [xml](get-content d:\temp\parent.xml)
$parentnode = $parent.manifest.manifestexecution.assetdetail
$child = [xml](get-content d:\temp\child.xml)
$childnode = $child.manifest.manifestexecution.assetdetail
while ($childnode.haschildnodes) {
$cn = $childnode.firstchild
$cn = $childnode.removechild($cn)
$cn = $parentnode.ownerdocument.importnode($cn, $true)
$parentnode.appendchild($cn)
}
Fortunately, most of these methods return the same XmlNode
or a new version of it, so the body of the while
loop could chained together like this:
$parentnode.appendchild( $parentnode.ownerdocument.importnode( $childnode.removechild( $childnode.firstchild ), $true ))
InsertAfter(newChild,referenceChild)
could also work, but would be done a little differently since it also needs a reference to the the node that it will be inserted after.