PoshCode Logo PowerShell Code Repository

New-XML (modification of post by view diff)
View followups from Joel Bennett | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1233"></script>download | new post

This is a first stab at creating a little DSL to generate XML. Note that I used System.Linq.XML (and output an XDocument) instead of the old XmlDocument… This means you have to have .Net 3.5 (LINQ) installed. It also means that if you want to be able to use the output via PowerShell’s magic XML dot-notation, you have to cast it to XmlDocument, just write: [xml]$xml = New-XML ...

  1. ###  A first stab at the worlds simplest DSL:
  2. ###  How to generate XML from PowerShell, in code instead of string-substitution
  3.  
  4. $xlr8r = [type]::gettype("System.Management.Automation.TypeAccelerators")  
  5. $xlinq = [Reflection.Assembly]::Load("System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
  6. $xlinq.GetTypes() | ? { $_.IsPublic -and !$_.IsSerializable -and $_.Name -ne "Extensions" } | % {
  7.    $xlr8r::Add( $_.Name, $_.FullName )
  8. }
  9.  
  10. function New-Xml {
  11.    Param([String]$root)
  12.    New-Object XDocument (New-Object XDeclaration "1.0","utf-8","no"),(
  13.       New-Object XElement $(
  14.          $root
  15.          #  foreach($ns in $namespace){
  16.             #  $name,$url = $ns -split ":",2
  17.             #  New-Object XAttribute ([XNamespace]::Xmlns + $name),$url
  18.          #  }
  19.          while($args) {
  20.             $attrib, $value, $args = $args
  21.             if($attrib -is [ScriptBlock]) {
  22.                &$attrib
  23.             } elseif ( $value -is [ScriptBlock] -and "-Content".StartsWith($attrib)) {
  24.                &$value
  25.             } elseif ( $value -is [XNamespace]) {
  26.                New-Object XAttribute ([XNamespace]::Xmlns + $attrib.TrimStart("-")),$value
  27.             } else {
  28.                New-Object XAttribute $attrib.TrimStart("-"), $value
  29.             }
  30.          }
  31.       ))
  32. }
  33.  
  34. function New-Element {
  35.    Param([String]$tag)
  36.    New-Object XElement $(
  37.       $tag
  38.       while($args) {
  39.          $attrib, $value, $args = $args
  40.          if($attrib -is [ScriptBlock]) {
  41.             &$attrib
  42.          } elseif ( $value -is [ScriptBlock] -and "-Content".StartsWith($attrib)) {
  43.             &$value
  44.          } elseif ( $value -is [XNamespace]) {
  45.                New-Object XAttribute ([XNamespace]::Xmlns + $attrib.TrimStart("-")),$value
  46.          } else {
  47.             New-Object XAttribute $attrib.TrimStart("-"), $value
  48.          }
  49.       }
  50.    )
  51. }
  52. Set-Alias xe New-Element
  53.  
  54.  
  55. ####################################################################################################
  56. ###### EXAMPLE SCRIPT:
  57. # [XNamespace]$dc = "http://purl.org/dc/elements/1.1"
  58. #
  59. # $xml = New-Xml rss -dc $dc -atom $atom -content $content -version "2.0" {
  60. #    xe channel {
  61. #       xe title {"Test RSS Feed"}
  62. #       xe link {"http`://HuddledMasses.org"}
  63. #       xe description {"An RSS Feed generated simply to demonstrate my XML DSL"}
  64. #       xe ($dc + "language") {"en"}
  65. #       xe ($dc + "creator") {"Jaykul@HuddledMasses.org"}
  66. #       xe ($dc + "rights") {"Copyright 2009, CC-BY"}
  67. #       xe ($dc + "date") {(Get-Date -f u) -replace " ","T"}
  68. #       xe item {
  69. #          xe title {"The First Item"}
  70. #          xe link {"htt`p://huddledmasses.org/new-site-new-layout-lost-posts/"}
  71. #          xe guid -isPermaLink true {"http`://huddledmasses.org/new-site-new-layout-lost-posts/"}
  72. #          xe description {"Ema Lazarus' Poem"}
  73. #          xe pubDate  {(Get-Date 10/31/2003 -f u) -replace " ","T"}
  74. #       }
  75. #    }
  76. # }
  77. #
  78. # $xml.ToString()
  79. #
  80. ####### OUTPUT: (NOTE: I added the space in the http: to paste it here -- those aren't in the output)
  81. # <rss xmlns:dc="http ://purl.org/dc/elements/1.1" version="2.0">
  82. #   <channel>
  83. #     <title>Test RSS Feed</title>
  84. #     <link>http ://HuddledMasses.org</link>
  85. #     <description>An RSS Feed generated simply to demonstrate my XML DSL</description>
  86. #     <dc:language>en</dc:language>
  87. #     <dc:creator>Jaykul@HuddledMasses.org</dc:creator>
  88. #     <dc:rights>Copyright 2009, CC-BY</dc:rights>
  89. #     <dc:date>2009-07-26T00:50:08Z</dc:date>
  90. #     <item>
  91. #       <title>The First Item</title>
  92. #       <link>http ://huddledmasses.org/new-site-new-layout-lost-posts/</link>
  93. #       <guid isPermaLink="true">http ://huddledmasses.org/new-site-new-layout-lost-posts/</guid>
  94. #       <description>Ema Lazarus' Poem</description>
  95. #       <pubDate>2003-10-31T00:00:00Z</pubDate>
  96. #     </item>
  97. #   </channel>
  98. # </rss>

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