PoshCode Logo PowerShell Code Repository

JSON by Joel Bennett 26 months ago (modification of post by Joel Bennett view diff)
View followups from Joel Bennett | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1514"></script>download | new post

Version 1.0 of my JSON module. I has a full set of tools for exporting, importing, and converting Json objects (including arbitrary objects). See comments in script header for usage examples, but basically, you can do things like:

ls | ConvertTo-Json -Depth 2
ls | Select FullName, Length | ConvertTo-JSon -NoType

You can do full round-trips, even with partial data, as long as you specify the Type when converting back from JSON:

PS | Select PM, WS, CPU, ID, ProcessName | ConvertTo-json -NoType | ConvertFrom-json -Type System.Diagnostics.Process

  1. #requires -version 2.0
  2. # Version History:
  3. # v 0.5 - First Public version
  4. # v 1.0 - Made ConvertFrom-Json work with arbitrary JSON
  5. #       - switched to xsl style sheets for ConvertTo-JSON
  6.  
  7. #  There is no help (yet) because I'm still changing and renaming everything every time I mess with this code
  8. #  Full RoundTrip capability:
  9. #
  10. #  > ls | ConvertTo-Json | ConvertFrom-Json
  11. #  > ps | ConvertTo-Json | Convert-JsonToXml | Convert-XmlToJson | convertFrom-Json
  12. #
  13. #  You may frequently want to use the DEPTH or NoTypeInformation parameters:
  14. #
  15. #  > ConvertTo-Json -Depth 2 -NoTypeInformation
  16. #
  17. #  But then you have to specify the type when you reimport (and you can't do that for deep objects).  
  18. #  This problem also occurs if you convert the result of a SELECT statement (ie: PSCustomObject).
  19. #  For Example:
  20. #
  21. #  >  PS | Select PM, WS, CPU, ID, ProcessName |
  22. #  >> ConvertTo-json -NoType |
  23. #  >> ConvertFrom-json -Type System.Diagnostics.Process
  24.  
  25.  
  26. Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
  27. $utf8 = [System.Text.Encoding]::UTF8
  28.  
  29. function Write-String {
  30. PARAM(
  31.    [Parameter()]$stream,
  32.    [Parameter(ValueFromPipeline=$true)]$string
  33. )
  34. PROCESS {
  35.   $bytes = $utf8.GetBytes($string)
  36.   $stream.Write( $bytes, 0, $bytes.Length )
  37. }  
  38. }
  39.  
  40. function Convert-JsonToXml {
  41. PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
  42. BEGIN {
  43.    $mStream = New-Object System.IO.MemoryStream
  44. }
  45. PROCESS {
  46.    $json | Write-String -stream $mStream
  47. }
  48. END {
  49.    $mStream.Position = 0
  50.    $jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
  51.    try
  52.    {
  53.       $xml = New-Object Xml.XmlDocument
  54.       $xml.Load($jsonReader)
  55.       $xml
  56.    }
  57.    finally
  58.    {
  59.       $jsonReader.Close()
  60.       $mStream.Dispose()
  61.    }
  62. }
  63. }
  64.  
  65. function Convert-XmlToJson {
  66. PARAM([Parameter(ValueFromPipeline=$true)][Xml]$xml)
  67. PROCESS {
  68.    $mStream = New-Object System.IO.MemoryStream
  69.    $jsonWriter = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonWriter($mStream)
  70.    try
  71.    {
  72.      $xml.Save($jsonWriter)
  73.      $bytes = $mStream.ToArray()
  74.      [System.Text.Encoding]::UTF8.GetString($bytes,0,$bytes.Length)
  75.    }
  76.    finally
  77.    {
  78.      $jsonWriter.Close()
  79.      $mStream.Dispose()
  80.    }
  81. }
  82. }
  83.  
  84. ## Rather than rewriting ConvertTo-Xml ...
  85. Function ConvertTo-Json {
  86. [CmdletBinding()]
  87. Param(
  88.    [Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$true)]$InputObject
  89. ,
  90.    [Parameter(Mandatory=$false)][Int]$Depth=1
  91. ,
  92.    [Switch]$NoTypeInformation
  93. )
  94. END {
  95.    ## You must output ALL the input at once
  96.    ## ConvertTo-Xml outputs differently if you just have one, so your results would be different
  97.    $input | ConvertTo-Xml -Depth:$Depth -NoTypeInformation:$NoTypeInformation -As Document | Convert-CliXmlToJson
  98. }
  99. }
  100.  
  101. Function Convert-CliXmlToJson {
  102. PARAM(
  103.    [Parameter(ValueFromPipeline=$true)][Xml.XmlNode]$xml
  104. )
  105. BEGIN {
  106.    $xmlToJsonXsl = @'
  107. <?xml version="1.0" encoding="UTF-8"?>
  108. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  109. <!--
  110.  CliXmlToJson.xsl
  111.  
  112.  Copyright (c) 2006,2008 Doeke Zanstra
  113.  Copyright (c) 2009 Joel Bennett
  114.  All rights reserved.
  115.  
  116.  Redistribution and use in source and binary forms, with or without modification,
  117.  are permitted provided that the following conditions are met:
  118.  
  119.  Redistributions of source code must retain the above copyright notice, this
  120.  list of conditions and the following disclaimer. Redistributions in binary
  121.  form must reproduce the above copyright notice, this list of conditions and the
  122.  following disclaimer in the documentation and/or other materials provided with
  123.  the distribution.
  124.  
  125.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  126.  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  127.  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  128.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  129.  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  130.  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  131.  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  132.  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  133.  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  134.  THE POSSIBILITY OF SUCH DAMAGE.
  135. -->
  136.  
  137.  <xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="text/x-json"/>
  138.         <xsl:strip-space elements="*"/>
  139.  <!--contant-->
  140.  <xsl:variable name="d">0123456789</xsl:variable>
  141.  
  142.  <!-- ignore document text -->
  143.  <xsl:template match="text()[preceding-sibling::node() or following-sibling::node()]"/>
  144.  
  145.  <!-- string -->
  146.  <xsl:template match="text()">
  147.    <xsl:call-template name="escape-string">
  148.      <xsl:with-param name="s" select="."/>
  149.    </xsl:call-template>
  150.  </xsl:template>
  151.  
  152.  <!-- Main template for escaping strings; used by above template and for object-properties
  153.       Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
  154.  <xsl:template name="escape-string">
  155.    <xsl:param name="s"/>
  156.    <xsl:text>"</xsl:text>
  157.    <xsl:call-template name="escape-bs-string">
  158.      <xsl:with-param name="s" select="$s"/>
  159.    </xsl:call-template>
  160.    <xsl:text>"</xsl:text>
  161.  </xsl:template>
  162.  
  163.  <!-- Escape the backslash (\) before everything else. -->
  164.  <xsl:template name="escape-bs-string">
  165.    <xsl:param name="s"/>
  166.    <xsl:choose>
  167.      <xsl:when test="contains($s,'\')">
  168.        <xsl:call-template name="escape-quot-string">
  169.          <xsl:with-param name="s" select="concat(substring-before($s,'\'),'\\')"/>
  170.        </xsl:call-template>
  171.        <xsl:call-template name="escape-bs-string">
  172.          <xsl:with-param name="s" select="substring-after($s,'\')"/>
  173.        </xsl:call-template>
  174.      </xsl:when>
  175.      <xsl:otherwise>
  176.        <xsl:call-template name="escape-quot-string">
  177.          <xsl:with-param name="s" select="$s"/>
  178.        </xsl:call-template>
  179.      </xsl:otherwise>
  180.    </xsl:choose>
  181.  </xsl:template>
  182.  
  183.  <!-- Escape the double quote ("). -->
  184.  <xsl:template name="escape-quot-string">
  185.    <xsl:param name="s"/>
  186.    <xsl:choose>
  187.      <xsl:when test="contains($s,'&quot;')">
  188.        <xsl:call-template name="encode-string">
  189.          <xsl:with-param name="s" select="concat(substring-before($s,'&quot;'),'\&quot;')"/>
  190.        </xsl:call-template>
  191.        <xsl:call-template name="escape-quot-string">
  192.          <xsl:with-param name="s" select="substring-after($s,'&quot;')"/>
  193.        </xsl:call-template>
  194.      </xsl:when>
  195.      <xsl:otherwise>
  196.        <xsl:call-template name="encode-string">
  197.          <xsl:with-param name="s" select="$s"/>
  198.        </xsl:call-template>
  199.      </xsl:otherwise>
  200.    </xsl:choose>
  201.  </xsl:template>
  202.  
  203.  <!-- Replace tab, line feed and/or carriage return by its matching escape code. Can't escape backslash
  204.        or double quote here, because they don't replace characters (&#x0; becomes \t), but they prefix
  205.       characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be
  206.       processed first. This function can't do that. -->
  207.   <xsl:template name="encode-string">
  208.     <xsl:param name="s"/>
  209.     <xsl:choose>
  210.       <!-- tab -->
  211.       <xsl:when test="contains($s,'&#x9;')">
  212.         <xsl:call-template name="encode-string">
  213.           <xsl:with-param name="s" select="concat(substring-before($s,'&#x9;'),'\t',substring-after($s,'&#x9;'))"/>
  214.         </xsl:call-template>
  215.       </xsl:when>
  216.       <!-- line feed -->
  217.       <xsl:when test="contains($s,'&#xA;')">
  218.         <xsl:call-template name="encode-string">
  219.           <xsl:with-param name="s" select="concat(substring-before($s,'&#xA;'),'\n',substring-after($s,'&#xA;'))"/>
  220.         </xsl:call-template>
  221.       </xsl:when>
  222.       <!-- carriage return -->
  223.       <xsl:when test="contains($s,'&#xD;')">
  224.         <xsl:call-template name="encode-string">
  225.           <xsl:with-param name="s" select="concat(substring-before($s,'&#xD;'),'\r',substring-after($s,'&#xD;'))"/>
  226.         </xsl:call-template>
  227.       </xsl:when>
  228.       <xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
  229.     </xsl:choose>
  230.   </xsl:template>
  231.  
  232.   <!-- number (no support for javascript mantise) -->
  233.   <xsl:template match="text()[not(string(number())='NaN' or
  234.                       (starts-with(.,'0' ) and . != '0'))]">
  235.     <xsl:value-of select="."/>
  236.   </xsl:template>
  237.  
  238.   <!-- boolean, case-insensitive -->
  239.   <xsl:template match="text()[translate(.,'TRUE','true')='true']">true</xsl:template>
  240.   <xsl:template match="text()[translate(.,'FALSE','false')='false']">false</xsl:template>
  241.  
  242.   <!-- root object(s) -->
  243.   <xsl:template match="*" name="base">
  244.     <xsl:if test="not(preceding-sibling::*)">
  245.       <xsl:choose>
  246.         <xsl:when test="count(../*)>1"><xsl:text>[</xsl:text></xsl:when>
  247.         <xsl:otherwise><xsl:text>{</xsl:text></xsl:otherwise>
  248.       </xsl:choose>
  249.     </xsl:if>
  250.     <xsl:call-template name="escape-string">
  251.       <xsl:with-param name="s" select="name()"/>
  252.     </xsl:call-template>
  253.     <xsl:text>:</xsl:text>
  254.     <!-- check type of node -->
  255.     <xsl:choose>
  256.       <!-- null nodes -->
  257.       <xsl:when test="count(child::node())=0">null</xsl:when>
  258.       <!-- other nodes -->
  259.       <xsl:otherwise>
  260.         <xsl:apply-templates select="child::node()"/>
  261.       </xsl:otherwise>
  262.     </xsl:choose>
  263.     <!-- end of type check -->
  264.     <xsl:if test="following-sibling::*">,</xsl:if>
  265.     <xsl:if test="not(following-sibling::*)">
  266.       <xsl:choose>
  267.         <xsl:when test="count(../*)>1"><xsl:text>]</xsl:text></xsl:when>
  268.         <xsl:otherwise><xsl:text>}</xsl:text></xsl:otherwise>
  269.       </xsl:choose>
  270.     </xsl:if>
  271.   </xsl:template>
  272.  
  273.   <!-- properties of objects -->
  274.   <xsl:template match="*[count(../*[name(../*)=name(.)])=count(../*) and count(../*)&gt;1]">
  275.     <xsl:variable name="inArray" select="translate(local-name(),'OBJECT','object')='object' or ../@Type[starts-with(.,'System.Collections') or contains(.,'[]') or (contains(.,'[') and contains(.,']'))]"/>
  276.     <xsl:if test="not(preceding-sibling::*)">
  277.        <xsl:choose>
  278.          <xsl:when test="$inArray"><xsl:text>[</xsl:text></xsl:when>
  279.          <xsl:otherwise>
  280.             <xsl:text>{</xsl:text>
  281.             <xsl:if test="../@Type">
  282.                <xsl:text>"__type":</xsl:text>      
  283.                <xsl:call-template name="escape-string">
  284.                  <xsl:with-param name="s" select="../@Type"/>
  285.                </xsl:call-template>
  286.                <xsl:text>,</xsl:text>      
  287.              </xsl:if>
  288.          </xsl:otherwise>
  289.        </xsl:choose>
  290.     </xsl:if>
  291.     <xsl:choose>
  292.       <xsl:when test="not(child::node())">
  293.         <xsl:call-template name="escape-string">
  294.           <xsl:with-param name="s" select="@Name"/>
  295.         </xsl:call-template>
  296.         <xsl:text>:null</xsl:text>
  297.       </xsl:when>
  298.       <xsl:when test="$inArray">
  299.         <xsl:apply-templates select="child::node()"/>
  300.       </xsl:when>
  301.       <!--
  302.       <xsl:when test="not(@Name) and not(@Type)">
  303.         <xsl:call-template name="escape-string">
  304.           <xsl:with-param name="s" select="local-name()"/>
  305.         </xsl:call-template>
  306.         <xsl:text>:</xsl:text>      
  307.         <xsl:apply-templates select="child::node()"/>
  308.       </xsl:when>
  309.       -->
  310.       <xsl:when test="not(@Name)">
  311.         <xsl:call-template name="escape-string">
  312.           <xsl:with-param name="s" select="local-name()"/>
  313.         </xsl:call-template>
  314.         <xsl:text>:</xsl:text>      
  315.         <xsl:apply-templates select="child::node()"/>
  316.       </xsl:when>
  317.       <xsl:otherwise>
  318.         <xsl:call-template name="escape-string">
  319.           <xsl:with-param name="s" select="@Name"/>
  320.         </xsl:call-template>
  321.         <xsl:text>:</xsl:text>
  322.         <xsl:apply-templates select="child::node()"/>
  323.       </xsl:otherwise>
  324.     </xsl:choose>
  325.     <xsl:if test="following-sibling::*">,</xsl:if>
  326.     <xsl:if test="not(following-sibling::*)">      
  327.       <xsl:choose>
  328.         <xsl:when test="$inArray"><xsl:text>]</xsl:text></xsl:when>
  329.         <xsl:otherwise><xsl:text>}</xsl:text></xsl:otherwise>
  330.       </xsl:choose>
  331.     </xsl:if>
  332.   </xsl:template>
  333.  
  334.  
  335.   <!-- convert root element to an anonymous container -->
  336.   <xsl:template match="/">
  337.     <xsl:apply-templates select="node()"/>
  338.   </xsl:template>    
  339. </xsl:stylesheet>
  340. '@
  341. }
  342. PROCESS {
  343.   if(Get-Member -InputObject $xml -Name root) {
  344.      Write-Verbose "Ripping to Objects"
  345.      $xml = $xml.root.Objects
  346.   } else {
  347.      Write-Verbose "Was already Objects"
  348.   }
  349.   Convert-Xml -Xml $xml -Xsl $xmlToJsonXsl
  350. }
  351. }
  352.  
  353. Function ConvertFrom-Xml {
  354.   [CmdletBinding(DefaultParameterSetName="AutoType")]
  355.   PARAM(
  356.      [Parameter(ValueFromPipeline=$true,Mandatory=$true,Position=1)]
  357.      [Xml.XmlNode]
  358.      $xml
  359.      ,
  360.      [Parameter(Mandatory=$true,ParameterSetName="ManualType")]
  361.      [Type]$Type
  362.      ,
  363.      [Switch]$ForceType
  364.   )
  365.   PROCESS{
  366.      if(Get-Member -InputObject $xml -Name root) {
  367.         return $xml.root.Objects |
  368.      } elseif(Get-Member -InputObject $xml -Name Objects) {
  369.         return $xml.Objects |
  370.      }
  371.      $propbag = @{}
  372.      foreach($name in Get-Member -InputObject $xml -MemberType Property | Where-Object{$_.Name -notmatch "^__|type"} | Select-Object -ExpandProperty name) {
  373.         Write-Verbose "$Name Type: $($xml."$Name".type)"
  374.         switch( $xml."$Name".type ) {
  375.            "object" {
  376.               $propbag."$Name" = ConvertFrom-Xml -Xml $xml."$Name"
  377.               break
  378.            }
  379.            "string" {
  380.               $propbag."$Name" = $xml."$Name".get_InnerText()
  381.               $MightBeADate = $xml."$Name".get_InnerText() -as [DateTime]
  382.               ## Strings that are actually dates (*grumble* JSON is crap)              
  383.               if($MightBeADate -and $propbag."$Name" -eq $MightBeADate.ToString("G")) {
  384.                  $propbag."$Name" = $MightBeADate
  385.               }
  386.               break
  387.            }
  388.            "number" {
  389.               $number = $xml."$Name".get_InnerText()
  390.               if($number -eq ($number -as [int])) {
  391.                  $propbag."$Name" = $number -as [int]
  392.               } elseif($number -eq ($number -as [double])) {
  393.                  $propbag."$Name" = $number -as [double]
  394.               } else {
  395.                  $propbag."$Name" = $number -as [decimal]
  396.               }
  397.               break
  398.            }
  399.            "boolean" {
  400.               $propbag."$Name" = [bool]::parse($xml."$Name".get_InnerText())
  401.            }
  402.            "null" {
  403.               $propbag."$Name" = $null
  404.            }
  405.            default {
  406.               $propbag."$Name" = $xml."$Name"
  407.               break
  408.            }
  409.         }
  410.      }
  411.      if(!$Type -and $xml.HasAttribute("__type")) { $Type = $xml.__Type }
  412.      if($ForceType -and $Type) {
  413.         try {
  414.            $output = New-Object $Type -Property $propbag
  415.         } catch {
  416.            $output = New-Object PSObject -Property $propbag
  417.            $output.PsTypeNames.Insert(0, $xml.__type)
  418.         }
  419.      } else {
  420.         $output = New-Object PSObject -Property $propbag
  421.         if($Type) {
  422.            $output.PsTypeNames.Insert(0, $Type)
  423.         }
  424.      }
  425.      Write-Output $output
  426.   }
  427. }
  428.  
  429. Function ConvertFrom-Json {
  430.   [CmdletBinding(DefaultParameterSetName="AutoType")]
  431. PARAM(
  432.   [Parameter(ValueFromPipeline=$true,Mandatory=$true,Position=1)][string]$InputObject
  433.   ,
  434.   [Parameter(Mandatory=$true,ParameterSetName="ManualType")][Type]$Type
  435.   ,
  436.   [Switch]$ForceType
  437. )
  438. PROCESS {
  439.   $null = $PSBoundParameters.Remove("InputObject")
  440.   (Convert-JsonToXml $InputObject).Root.Objects.Item.GetEnumerator() | ConvertFrom-Xml @PSBoundParameters
  441. }
  442. }
  443.  
  444. #########
  445. ### The JSON library is dependent on Convert-Xml from my Xml script module
  446.  
  447. function Convert-Node {
  448. param(
  449. [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
  450. [System.Xml.XmlReader]$XmlReader,
  451. [Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$false)]
  452. [System.Xml.Xsl.XslCompiledTransform]$StyleSheet
  453. )
  454. PROCESS {
  455.   $output = New-Object IO.StringWriter
  456.   $StyleSheet.Transform( $XmlReader, $null, $output )
  457.   Write-Output $output.ToString()
  458. }
  459. }
  460.  
  461. function Convert-Xml {
  462. #.Synopsis
  463. #  The Convert-XML function lets you use Xslt to transform XML strings and documents.
  464. #.Description
  465. #.Parameter Content
  466. #  Specifies a string that contains the XML to search. You can also pipe strings to Select-XML.
  467. #.Parameter Namespace
  468. #   Specifies a hash table of the namespaces used in the XML. Use the format @{<namespaceName> = <namespaceUri>}.
  469. #.Parameter Path
  470. #   Specifies the path and file names of the XML files to search.  Wildcards are permitted.
  471. #.Parameter Xml
  472. #  Specifies one or more XML nodes to search.
  473. #.Parameter Xsl
  474. #  Specifies an Xml StyleSheet to transform with...
  475. [CmdletBinding(DefaultParameterSetName="Xml")]
  476. PARAM(
  477.   [Parameter(Position=1,ParameterSetName="Path",Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
  478.   [ValidateNotNullOrEmpty()]
  479.   [Alias("PSPath")]
  480.   [String[]]$Path
  481. ,
  482.   [Parameter(Position=1,ParameterSetName="Xml",Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
  483.   [ValidateNotNullOrEmpty()]
  484.   [Alias("Node")]
  485.   [System.Xml.XmlNode[]]$Xml
  486. ,
  487.   [Parameter(ParameterSetName="Content",Mandatory=$true,ValueFromPipeline=$true)]
  488.   [ValidateNotNullOrEmpty()]
  489.   [String[]]$Content
  490. ,
  491.   [Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false)]
  492.   [ValidateNotNullOrEmpty()]
  493.   [Alias("StyleSheet")]
  494.   [String[]]$Xslt
  495. )
  496. BEGIN {
  497.   $StyleSheet = New-Object System.Xml.Xsl.XslCompiledTransform
  498.   if(Test-Path @($Xslt)[0] -ErrorAction 0) {
  499.      Write-Verbose "Loading Stylesheet from $(Resolve-Path @($Xslt)[0])"
  500.      $StyleSheet.Load( (Resolve-Path @($Xslt)[0]) )
  501.   } else {
  502.      Write-Verbose "$Xslt"
  503.      $StyleSheet.Load(([System.Xml.XmlReader]::Create((New-Object System.IO.StringReader ($Xslt -join "`n")))))
  504.   }
  505.   [Text.StringBuilder]$XmlContent = [String]::Empty
  506. }
  507. PROCESS {
  508.   switch($PSCmdlet.ParameterSetName) {
  509.      "Content" {
  510.         $null = $XmlContent.AppendLine( $Content -Join "`n" )
  511.      }
  512.      "Path" {
  513.         foreach($file in Get-ChildItem $Path) {
  514.            Convert-Node -Xml ([System.Xml.XmlReader]::Create((Resolve-Path $file))) $StyleSheet
  515.         }
  516.      }
  517.      "Xml" {
  518.         foreach($node in $Xml) {
  519.            Convert-Node -Xml (New-Object Xml.XmlNodeReader $node) $StyleSheet
  520.         }
  521.      }
  522.   }
  523. }
  524. END {
  525.   if($PSCmdlet.ParameterSetName -eq "Content") {
  526.      [Xml]$Xml = $XmlContent.ToString()
  527.      Convert-Node -Xml $Xml $StyleSheet
  528.   }
  529. }
  530. }
  531.  
  532.  
  533. New-Alias fromjson ConvertFrom-Json
  534. New-Alias tojson ConvertTo-Json
  535.  
  536. #New-Alias ipjs Import-Json
  537. #New-Alias epjs Export-Json
  538. #Import-Json, Export-Json,
  539.  
  540. Export-ModuleMember -Function ConvertFrom-Json, ConvertTo-Json, Convert-JsonToXml, Convert-XmlToJson, Convert-CliXmlToJson -Alias *

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me