1

I want to print the angular brackets(<,>) in powershell, but it is printing to > and < instead respectively. Is there any way I can print those symbols.

I have used \ to overcome the bracket's escape properties and also single inverted commas but the result remains same.

$xml = [xml](Get-Content -Path C:\Users\Desktop\new.xml)
$xml.Deploy.app="$<abc\bc>"
$xml.Save("C:\Users\Desktop\new.xml")

I expected output to be

<?xml version="1.0"?> 
<Deploy>
  <app><abc\bc></app>
</Deploy>

but it printing

<?xml version="1.0"?>
<Deploy>
  <app>&lt;abc\bc&gt;</app>
</Deploy>

Thanks in advance!!

Theo
  • 57,719
  • 8
  • 24
  • 41
  • Try creating a new node (as a subnode of `$xml.Deploy.app`) with the oddball name `abc\ab`. – Jeff Zeitlin Apr 02 '19 at 18:37
  • I have updated my answer to hopefully explain better why some characters in XML are converted into their entity format. Also, it shows you CAN have characters like `<` and `>` unchanged in XML, but only if you insert them as a `CDATA` section. – Theo Apr 04 '19 at 12:16

2 Answers2

2

XML needs 5 characters to be replaced, because they have special meaning in XML. These characters are <>&'" Here, you can not simply prepend these characters with some escape character like the backslash, instead they need to be converted into named or numbered entities.

As you have noticed, this conversion happens automatically in [xml], but there are also a number of ways to do that manually if needed:

$str = "$<abc\bc>"

1) Using the String .Replace() method:

$str.Replace("&", "&amp;").Replace("'", "&apos;").Replace('"', "&quot;").Replace("<", "&lt;").Replace(">", "&gt;")

2) Using .Net System.Security:

 Add-Type -AssemblyName System.Security
 [System.Security.SecurityElement]::Escape($str)

3) Using System.Xml.XmlDocument:

[xml]$doc = New-Object System.Xml.XmlDocument
$node = $doc.CreateElement("root")
$node.InnerText = $str
$node.InnerXml

4) Using Regex:

$str -ireplace '&#34;|&#x(?:00)?22;|"', '&quot;' `
     -ireplace "&#39;|&#x(?:00)?27;|'", '&apos;' `
     -ireplace '&#60;|&#x(?:00)?3C;|<', '&lt;'   `
     -ireplace '&#62;|&#x(?:00)?3E;|>', '&gt;'   `
     -ireplace '&#38;|&#x(?:00)?26;|&(?!(?:[a-z]+|#[0-9]+|#x[0-9a-f]+);)', '&amp;'

All of the above will convert the XML special characters into entities, so the result will look like this:

$&lt;abc\bc&gt;


If you absolutely don't want the XML special characters to be converted into entities, then there is AFAIK only the option to set the value as a CDATA section, which will wrap your string inside <![CDATA[ and ]]>]. To use that in your example, change the line $xml.Deploy.app="$<abc\bc>" into this:

$xml['Deploy']['app'].AppendChild($xml.CreateCDataSection("$<abc\bc>")) | Out-Null

Now it will print:

<?xml version="1.0"?>
<Deploy>
  <app><![CDATA[$<abc\bc>]]></app>
</Deploy>

To read back this CDATA value as string, you can do either $value = $xml.Deploy.app.InnerText or $value = $xml.Deploy.app.'#cdata-section'

Hope that explains

Theo
  • 57,719
  • 8
  • 24
  • 41
  • This happens automatically when you work with it as `[xml]` in PowerShell and save it that way. This is the opposite of what the user wants. – TheMadTechnician Apr 03 '19 at 17:33
  • @TheMadTechnician It is explaining why the characters are converted in XML and that what the OP expects is not possible in XML. – Theo Apr 03 '19 at 18:28
  • @TheMadTechnician You're right, the explaining part could have been a lot better. I have reworded my answer. – Theo Apr 04 '19 at 12:21
  • Excellent update! I've upvoted, and encourage the OP to accept this answer to help future searchers, and to give credit where credit is due. – TheMadTechnician Apr 04 '19 at 19:18
0

This is just how XML works. The less than and greater than characters are reserved/special characters. When a value includes them it will convert them to their escaped forms &lt; and &gt;. What you expect to be output is invalid XML.

TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56
  • So how can I get <> in xml files? – Chandan chandu Apr 03 '19 at 03:06
  • You don't in the XML document that is saved to drive. Any XML parser will convert `<` into `<` when it reads the XML file in, the same as any reserved character like that. You can test that by loading your saved XML file with the `<` and what not in it, and then looking at the node's value. – TheMadTechnician Apr 03 '19 at 17:37