Home > other >  How can I have an = sign in an XML?
How can I have an = sign in an XML?

Time:12-15

I have a Powershell script which calls an XML, gets a URL, and tries to open Chrome to that URL. Downside, the URL contains the = character, and none of the character escape suggestions I've seen work.

Here's the XML:

<Config>
    <Stuff>
        <Application Name="Place" CaptivePortal="https://website.com:1337/php/uid.php?thing=1&stuff=0" RDP="192.168.1.1" Entitlement="Admin" />
    </Stuff>
</Config>

And here's the section of the PS scripts that's calling it:

Function func_launch_Stuff($v_func_parm_launch_type, $v_func_parm_launch_element){

    # launch based on type
    switch ($v_func_parm_launch_type)
    {
        "URL" {
            $v_Application_Launch = "C:\Program Files\Google\Chrome\Application\chrome.exe"
            $v_Application_Argument = "$($v_func_parm_launch_element)"
            Start-Process -FilePath $v_Application_Launch -ArgumentList $v_Application_Argument -Wait}
}
}

[xml]$v_XML_Config_File = Get-Content -Path $v_parm_XML_Config_File

I've trimmed out other sections, because this is the only one throwing errors. I'd go into changing the original script more, but it was hand crafted by an engineer we don't have anymore, and I'm not good enough with PS to redo this myself in a way that'll handle my issue without making 10 more.

I've tried using the four options from here, and manually replacing the = character with =. It always throws the error below, with X replaced by =, `=, or &.

"Error message: Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "'X' is an unexpected token."

CodePudding user response:

Your XML is malformed:

  • It contains an unescaped & character (&stuff=0), which is the cause of your problem: what follows it is considered part of an XML entity reference, and since & is not the start of one in your document, parsing breaks, namely when the = is encountered (given that = isn't a legal character in the name of an entity reference).

  • Replace & with &amp; - i.e. the entity reference that represents a literal & - and your problem goes away:

# OK, because "&" was escaped as "&amp;"
[xml] @'
<Config>
    <Stuff>
        <Application Name="Place" CaptivePortal="https://website.com:1337/php/uid.php?thing=1&amp;stuff=0" RDP="192.168.1.1" Entitlement="Admin" />
    </Stuff>
</Config>
'@

If you cannot fix the problem at the source, perform a string replacement (using a simplified example):

# Replace '&' with '&amp;' before casting to [xml]
[xml] (@'
  <Config>
    <Foo Url="https://example.org?foo&bar"/>
  </Config>
'@).Replace('&', '&amp;')

Note: This simple approach assumes that your document does not contain & characters that are part of valid entity references already. You'd need a more sophisticated approach, using regexes to handle that case.


As an aside re parsing XML from files:

 [xml]$v_XML_Config_File = Get-Content -Path $v_parm_XML_Config_File
  • You can speed up your command by adding -Raw to the Get-Content call, which causes it to read the entire file as a whole.

  • However, this - convenient - approach is not fully robust, as Get-Content may misinterpret the character encoding of your input file.

    • A fully robust (but less convenient) solution is:

      ($v_XML_Config_File = [xml]::new()).Load((Convert-Path $v_parm_XML_Config_File))
      
    • See the bottom section of this answer for details.

CodePudding user response:

Your last line in sample code should be changed...

From:

[xml]$v_XML_Config_File = Get-Content -Path $v_parm_XML_Config_File

To:

[xml]$v_XML_Config_File = Get-Content -Path $v_parm_XML_Config_File | ConvertTo-Xml

I've tested sample xml which you posted and got errors, by piping to ConverTo-Xml it worked.

  • Related