我怎么能有一个=符号在XML?



我有一个Powershell脚本调用XML,得到一个URL,并试图打开Chrome到该URL。缺点是,URL包含=字符,并且我所见过的字符转义建议都不起作用。

这是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>

这里是PS脚本中调用它的部分:

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 FilesGoogleChromeApplicationchrome.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

我已经删除了其他部分,因为这是唯一一个抛出错误的部分。我想对原始脚本进行更多的修改,但它是由我们现在没有的工程师手工制作的,而且我对PS的能力不够好,无法自己重做,以解决我的问题,而不需要再做10个。

我试过使用这里的四个选项,并手动将=字符替换为=。它总是抛出下面的错误,带有X由=、' =或&代替。

"错误信息:无法转换值"System.Object[]"键入"system . xml . xmldocument"。错误:"'X'是一个意外的标记。">

您的XML格式不正确:

  • 它包含一个未转义的&字符(&stuff=0),这是您的问题的原因:它被认为是XML实体引用的一部分,并且由于&不是在您的文档中的开始,解析打破,即当=遇到时(给定=不是实体引用名称中的合法字符)。

  • &替换为&amp;-即代表文字&的实体引用-您的问题就解决了:

# 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>
'@

如果不能从源头解决问题,请执行字符串替换(使用简化示例):

# Replace '&' with '&amp;' before casting to [xml]
[xml] (@'
<Config>
<Foo Url="https://example.org?foo&bar"/>
</Config>
'@).Replace('&', '&amp;')
注意:这个简单的方法假定您的文档不包含已经是有效实体引用的部分的&字符。您需要一种更复杂的方法,使用正则表达式来处理这种情况。

作为旁白从文件解析XML:

[xml]$v_XML_Config_File = Get-Content -Path $v_parm_XML_Config_File
  • 您可以通过将-Raw添加到Get-Content调用中来加快命令的速度,这会导致它将整个文件作为一个整体读取

  • 然而,这种方便的方法不是完全健壮的,因为Get-Content可能会误解输入文件的字符编码。

    • 一个完全健壮(但不太方便)的解决方案是:

      ($v_XML_Config_File = [xml]::new()).Load((Convert-Path $v_parm_XML_Config_File))
      
    • 详细信息请参见此回答的底部部分。

示例代码的最后一行应该更改…

来自:

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

:

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

我已经测试了您发布并得到错误的示例xml,通过管道到ConverTo-Xml它工作。