XML необходимо заменить 5 символов, потому что они имеют особое значение в XML. Эти символы <>&'"
Здесь вы не можете просто добавить эти символы к какому-либо управляющему символу, например к обратной косой черте, вместо этого их необходимо преобразовать в именованные или пронумерованные сущности .
Как вы заметили, это преобразование происходит автоматически в [xml]
, но есть также несколько способов сделать это вручную, если необходимо:
$str = "$<abc\bc>"
1) Использование метода String .Replace()
:
$str.Replace("&", "&").Replace("'", "'").Replace('"', """).Replace("<", "<").Replace(">", ">")
2) Использование .Net System.Security:
Add-Type -AssemblyName System.Security
[System.Security.SecurityElement]::Escape($str)
3) Использование System.Xml.XmlDocument:
[xml]$doc = New-Object System.Xml.XmlDocument
$node = $doc.CreateElement("root")
$node.InnerText = $str
$node.InnerXml
4) Использование регулярных выражений:
$str -ireplace '"|&#x(?:00)?22;|"', '"' `
-ireplace "'|&#x(?:00)?27;|'", ''' `
-ireplace '<|&#x(?:00)?3C;|<', '<' `
-ireplace '>|&#x(?:00)?3E;|>', '>' `
-ireplace '&|&#x(?:00)?26;|&(?!(?:[a-z]+|#[0-9]+|#x[0-9a-f]+);)', '&'
Все вышеперечисленное преобразует специальные символы XML в сущности, поэтому результат будет выглядеть следующим образом:
$<abc\bc>
Если вы абсолютно не хотите, чтобы специальные символы XML конвертировались в сущности, существует только опция AFAIK для установки значения в виде секции CDATA , которая обернет вашу строку внутри <![CDATA[
и ]]>
].
Чтобы использовать это в вашем примере, измените строку $xml.Deploy.app="$<abc\bc>"
на следующую:
$xml['Deploy']['app'].AppendChild($xml.CreateCDataSection("$<abc\bc>")) | Out-Null
Теперь будет напечатано:
<?xml version="1.0"?>
<Deploy>
<app><![CDATA[$<abc\bc>]]></app>
</Deploy>
Чтобы прочитать это значение CDATA в виде строки, вы можете сделать $value = $xml.Deploy.app.InnerText
или $value = $xml.Deploy.app.'#cdata-section'
Надеюсь, что это объясняет