fix for ‘Cannot convert value “System.Xml.XmlElement” to type “System.Xml.XmlDocument”‘

Quick fix

Change:

Param( [xml]$WordpressPostAsXml

to

Param( [system.xml.xmlelement]$WordpressPostAsXml

Slightly More Detail

I’m in the process of coding a Powershell module to convert an xml file containing the content of my old WordPress site to a set of Markdown files for Hugo.

I got the error:

get-wpHugoFileName : Cannot process argument transformation on parameter 'WordpressPostAsXml'. Cannot convert value "System.Xml.XmlElement" to 
type "System.Xml.XmlDocument". Error: "The specified node cannot be inserted as the valid child of this node, because the specified node is the 
wrong type."
At C:\users\matt\Documents\WindowsPowershell\functions\function-get-WordpressContent.ps1:43 char:63
+ ... goFileName = get-wpHugoFileName -WordPressPost $WordPressPost -Conten ...
+                                                    ~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [get-wpHugoFileName], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,get-wpHugoFileName

In summary, there are three relevant functions

  • convert-wpPostToHugo – receieves an exported WordPress site in Xml format. Calls get-wpMatchingWordpressPosts to extract the specified bits, then get-wpHugoFileName for each post
  • get-wpMatchingWordpressPosts – extracts the xml nodes for posts which match a specified string
  • get-wpHugoFileName – called for each xml ‘node’. Returns a file name for the markdown content

convert-wpPostToHugo:

function  convert-wpPostToHugo{ 

  [CmdletBinding()]
  Param( [xml][Alias ("xml")]$WordpressXML = "$wp_xml",
         [string][Alias ("string")]$PostString = "ramone" ,
         [string][Alias ("f")]$ContentFolder = "c:\temp"
) 
  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

  $MatchingWordPressPosts = get-wpMatchingWordpressPosts -WordPressXml $WordPressXML -PostString $Poststring

  foreach ($WordPressPost in $MatchingWordPressPosts)
  {    
    [String]$HugoFileName = get-wpHugoFileName -WordPressPost $WordPressPost -ContentFolder $contentFolder
    write-verbose "`$HugoFileName: $HugoFileName"

get-wpMatchingWordpressPosts:

function get-wpMatchingWordpressPosts { 
  [CmdletBinding()]
  Param( [xml][Alias ("xml")]$WordpressXML = "$wp_xml",
         [string][Alias ("string")]$PostString = "ramone"         ) 

  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

  $Nodes = select-xml -xml $WordpressXML -xpath "//channel/item" | select -expandproperty node | where-object title -like "*$PostString*"


  return $nodes

get-wpHugoFileName:

function get-wpHugoFileName { 

  [CmdletBinding()]
  Param( [xml][Alias ("x")]$WordpressPostAsXml,
         [string][Alias ("f")]$ContentFolder = "c:\temp" )

  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

The fix was to change the definition of the $WordPressPost from xml to [system.xml.xmlelement]:
get-wpHugoFileName:

function get-wpHugoFileName { 

  [CmdletBinding()]
  Param( [system.xml.xmlelement][Alias ("x")]$WordpressPostAsXml,
         [string][Alias ("f")]$ContentFolder = "c:\temp" )

  write-debug "$(get-date -format 'hh:mm:ss.ffff') Function beg: $([string]$MyInvocation.Line) "

This makes sense….the variable returned from get-wpMatchingWordpressPosts is no longer a valid XML document – it is just elements of an XML document.

Advertisements