├── Build.PSake.ps1
├── ChangeLog.md
├── Examples
├── Example01.ps1
├── Example02.ps1
├── Example03.ps1
└── Example04.ps1
├── LICENSE
├── README.md
├── Src
├── Private
│ ├── Assert-XmlExFile.ps1
│ ├── Assert-XmlExXPath.ps1
│ └── Resolve-XmlExNamespace.ps1
└── Public
│ ├── Add-XmlExAttribute.ps1
│ ├── Add-XmlExComment.ps1
│ ├── Add-XmlExElement.ps1
│ ├── Add-XmlExNamespace.ps1
│ ├── Add-XmlExText.ps1
│ ├── Format-XmlEx.ps1
│ ├── New-XmlExDocument.ps1
│ ├── Set-XmlExConfigKeyValue.ps1
│ └── Set-XmlExDeclaration.ps1
├── Tests
├── Linting
│ ├── FileEncoding.Tests.ps1
│ ├── PSScriptAnalyzer.Tests.ps1
│ └── Style.Tests.ps1
└── Unit
│ └── Src
│ └── Public
│ ├── Add-XmlExAttribute.Tests.ps1
│ ├── Add-XmlExComment.Tests.ps1
│ ├── Add-XmlExElement.Tests.ps1
│ ├── Add-XmlExNamespace.Tests.ps1
│ ├── Add-XmlExText.Tests.ps1
│ ├── New-XmlExDocument.Tests.ps1
│ └── Set-XmlExDeclaration.Tests.ps1
├── VE_Certificate_2019.pfx.enc
├── XmlEx.nuspec
├── XmlEx.psd1
├── XmlEx.psm1
├── appveyor.yml
├── en-US
└── XmlEx.Resources.psd1
└── xml-tool-icon-53260.png
/Build.PSake.ps1:
--------------------------------------------------------------------------------
1 | #requires -Version 5;
2 | #requires -Modules VirtualEngine.Build;
3 |
4 | $psake.use_exit_on_error = $true;
5 |
6 | Properties {
7 | $moduleName = (Get-Item $PSScriptRoot\*.psd1)[0].BaseName;
8 | $basePath = $psake.build_script_dir;
9 | $buildDir = 'Release';
10 | $buildPath = (Join-Path -Path $basePath -ChildPath $buildDir);
11 | $releasePath = (Join-Path -Path $buildPath -ChildPath $moduleName);
12 | $thumbprint = '3DACD0F2D1E60EB33EC774B9CFC89A4BEE9037AF';
13 | $timeStampServer = 'http://timestamp.verisign.com/scripts/timestamp.dll';
14 | $exclude = @(
15 | '.git*',
16 | '.vscode',
17 | 'Release',
18 | 'Tests',
19 | 'Build.PSake.ps1',
20 | '*.png',
21 | '*.md',
22 | '*.enc',
23 | 'TestResults.xml',
24 | 'appveyor.yml',
25 | 'appveyor-tools'
26 | 'PScribo Test Doc.*',
27 | 'PScriboExample.*',
28 | 'TestResults.xml',
29 | 'Docs',
30 | '_DSCResources'
31 | );
32 | $signExclude = @('Examples','en-US');
33 | }
34 |
35 |
36 | # Synopsis: Initialises build variables
37 | Task Init {
38 |
39 | # Properties are not available in the script scope.
40 | Set-Variable manifest -Value (Get-ModuleManifest) -Scope Script;
41 | Set-Variable version -Value $manifest.Version -Scope Script;
42 | Write-Host (" Building module '{0}'." -f $manifest.Name) -ForegroundColor Yellow;
43 | Write-Host (" Building version '{0}'." -f $version) -ForegroundColor Yellow;
44 | } #end task Init
45 |
46 | # Synopsis: Cleans the release directory
47 | Task Clean -Depends Init {
48 |
49 | Write-Host (' Cleaning release directory "{0}".' -f $buildPath) -ForegroundColor Yellow;
50 | if (Test-Path -Path $buildPath) {
51 | Remove-Item -Path $buildPath -Include * -Recurse -Force;
52 | }
53 | [ref] $null = New-Item -Path $buildPath -ItemType Directory -Force;
54 | [ref] $null = New-Item -Path $releasePath -ItemType Directory -Force;
55 | } #end task Clean
56 |
57 | # Synopsis: Invokes Pester tests
58 | Task Test -Depends Init {
59 |
60 | $invokePesterParams = @{
61 | Path = "$basePath\Tests";
62 | OutputFile = "$basePath\TestResults.xml";
63 | OutputFormat = 'NUnitXml';
64 | Strict = $true;
65 | PassThru = $true;
66 | Verbose = $false;
67 | }
68 | $testResult = Invoke-Pester @invokePesterParams;
69 | if ($testResult.FailedCount -gt 0) {
70 | Write-Error ('Failed "{0}" unit tests.' -f $testResult.FailedCount);
71 | }
72 | }
73 |
74 | # Synopsis: Copies release files to the release directory
75 | Task Deploy -Depends Clean {
76 |
77 | Get-ChildItem -Path $basePath -Exclude $exclude | ForEach-Object {
78 | Write-Host (' Copying {0}' -f $PSItem.FullName) -ForegroundColor Yellow;
79 | Copy-Item -Path $PSItem -Destination $releasePath -Recurse;
80 | }
81 | } #end
82 |
83 | # Synopsis: Signs files in release directory
84 | Task Sign -Depends Deploy {
85 |
86 | if (-not (Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object Thumbprint -eq $thumbprint)) {
87 | ## Decrypt and import code signing cert
88 | .\appveyor-tools\secure-file.exe -decrypt .\VE_Certificate_2019.pfx.enc -secret $env:certificate_secret
89 | $certificatePassword = ConvertTo-SecureString -String $env:certificate_secret -AsPlainText -Force
90 | Import-PfxCertificate -FilePath .\VE_Certificate_2019.pfx -CertStoreLocation 'Cert:\CurrentUser\My' -Password $certificatePassword
91 | }
92 |
93 | Get-ChildItem -Path $releasePath -Exclude $signExclude | ForEach-Object {
94 | if ($PSItem -is [System.IO.DirectoryInfo]) {
95 | Get-ChildItem -Path $PSItem.FullName -Include *.ps* -Recurse | ForEach-Object {
96 | Write-Host (' Signing {0}' -f $PSItem.FullName) -ForegroundColor Yellow -NoNewline;
97 | $signResult = Set-ScriptSignature -Path $PSItem.FullName -Thumbprint $thumbprint -TimeStampServer $timeStampServer -ErrorAction Stop;
98 | Write-Host (' {0}.' -f $signResult.Status) -ForegroundColor Green;
99 | }
100 |
101 | }
102 | elseif ($PSItem.Name -like '*.ps*') {
103 | Write-Host (' Signing {0}' -f $PSItem.FullName) -ForegroundColor Yellow -NoNewline;
104 | $signResult = Set-ScriptSignature -Path $PSItem.FullName -Thumbprint $thumbprint -TimeStampServer $timeStampServer -ErrorAction Stop;
105 | Write-Host (' {0}.' -f $signResult.Status) -ForegroundColor Green;
106 | }
107 | }
108 | }
109 |
110 | Task Version -Depends Deploy {
111 |
112 | $nuSpecPath = Join-Path -Path $releasePath -ChildPath "$ModuleName.nuspec"
113 | $nuspec = [System.Xml.XmlDocument] (Get-Content -Path $nuSpecPath -Raw)
114 | $nuspec.Package.MetaData.Version = $version.ToString()
115 | $nuspec.Save($nuSpecPath)
116 | }
117 |
118 | # Synopsis: Publishes release module to PSGallery
119 | Task Publish_PSGallery -Depends Version {
120 |
121 | Publish-Module -Path $releasePath -NuGetApiKey "$env:gallery_api_key" -Verbose
122 | } #end task Publish
123 |
124 | # Synopsis: Creates release module Nuget package
125 | Task Package -Depends Build {
126 |
127 | $targetNuSpecPath = Join-Path -Path $releasePath -ChildPath "$ModuleName.nuspec"
128 | NuGet.exe pack "$targetNuSpecPath" -OutputDirectory "$env:TEMP"
129 | }
130 |
131 | # Synopsis: Publish release module to Dropbox repository
132 | Task Publish_Dropbox -Depends Package {
133 |
134 | $targetNuPkgPath = Join-Path -Path "$env:TEMP" -ChildPath "$ModuleName.$version.nupkg"
135 | $destinationPath = "$env:USERPROFILE\Dropbox\PSRepository"
136 | Copy-Item -Path "$targetNuPkgPath"-Destination $destinationPath -Force -Verbose
137 | }
138 |
139 | # Synopsis: Publish test results to AppVeyor
140 | Task AppVeyor {
141 |
142 | Get-ChildItem -Path "$basePath\*Results*.xml" | Foreach-Object {
143 | $address = 'https://ci.appveyor.com/api/testresults/nunit/{0}' -f $env:APPVEYOR_JOB_ID
144 | $source = $_.FullName
145 | Write-Verbose "UPLOADING TEST FILE: $address $source" -Verbose
146 | (New-Object 'System.Net.WebClient').UploadFile( $address, $source )
147 | }
148 | }
149 |
150 | Task Default -Depends Init, Clean, Test
151 | Task Build -Depends Default, Deploy, Version, Sign;
152 | Task Publish -Depends Build, Package, Publish_PSGallery
153 | Task Local -Depends Build, Package, Publish_Dropbox
154 |
--------------------------------------------------------------------------------
/ChangeLog.md:
--------------------------------------------------------------------------------
1 | # Change Log #
2 |
3 | ## 0.9.5 ##
4 |
5 | * Adds -Prepend switch to XmlComment
6 |
7 | ## 0.9.4 ##
8 |
9 | * Adds -NoPrefix switch parameter to XmlElement and XmlAttribute
10 | * Adds AppVeyor build
11 | * Adds linting tests
12 |
--------------------------------------------------------------------------------
/Examples/Example01.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | Import-Module -Name XmlEx -Force;
5 |
6 | $x = XmlDocument {
7 | XmlDeclaration -Encoding 'utf-8'
8 | XmlNamespace -Uri 'http://www.w3.org/XML/1998/namespace'
9 | XmlNamespace -Prefix 'v' -Uri 'http://mycustom/namespace'
10 | XmlNamespace -Prefix 'w' -Uri 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
11 | XmlElement -Name 'document' -Prefix w {
12 | XmlComment 'My comment'
13 | XmlElement -Name 'body' {
14 | XmlAttribute 'att1' 'value1' -Namespace 'http://www.w3.org/XML/1998/namespace'
15 | XmlAttribute 'att2' 'value2' -Prefix v
16 | XmlText 'My body value'
17 | }
18 | }
19 | } -Verbose
20 |
21 | $x | Format-XmlEx
22 |
--------------------------------------------------------------------------------
/Examples/Example02.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | Import-Module -Name XmlEx -Force;
5 |
6 | $x = [System.Xml.XmlDocument] @'
7 |
8 |
9 |
10 | Sub node
11 | '@
12 |
13 | ## Appending an XmlElement to an exising XmlElement
14 | XmlElement -Name 'appended' -XmlElement $x.document {
15 | XmlElement 'TextNode' {
16 | XmlText 'My text node'
17 | }
18 | } -Verbose
19 |
20 | ## Appending an XmlAttribute to an exising XmlElement
21 | [ref] $null = XmlAttribute -XmlElement $x.document.appended -Name 'myattribute' -Value 'Rubbish!' -verbose
22 |
23 | $x | Format-XmlEx
24 |
--------------------------------------------------------------------------------
/Examples/Example03.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | Import-Module -Name XmlEx -Force;
5 |
6 | $x = XmlDocument {
7 | XmlDeclaration
8 | }
9 |
10 | ## Appending an XmlElement to an exising XmlDocument
11 | XmlElement -XmlDocument $x -Name 'rootElement' {
12 | XmlElement 'TextNode' {
13 | XmlText 'My text node'
14 | }
15 | } -Verbose
16 |
17 | $x | Format-XmlEx
18 |
--------------------------------------------------------------------------------
/Examples/Example04.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | Import-Module -Name XmlEx -Force;
5 |
6 | $x = XmlDocument {
7 | XmlDeclaration -Encoding 'utf-8' -Standalone 'yes'
8 | XmlElement 'rootElement'
9 | }
10 |
11 | ## Appending an XmlElement to an exising root XmlElement. This is required because
12 | ## $x.rootElement is coerced into [System.String] (only applicable to the root node)?
13 | XmlElement -XmlElement $x.SelectSingleNode('/rootElement') -Name 'subElement' {
14 | XmlElement 'TextNode' {
15 | XmlText 'My text node'
16 | }
17 | } -Verbose
18 |
19 | $x | Format-XmlEx
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Iain Brighton
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://ci.appveyor.com/project/iainbrighton/xmlex)
2 |
3 | # XmlEx
4 |
5 | XmlEx (XML EXtensions) provides a PowerShell domain-specific language (DSL) to easily create and update XML documents without having to understand or manipulate the underlying [System.Xml.XmlDocument] objects. XmlEx provides a simple way to:
6 |
7 | * Create and append XML documents in PowerShell
8 | * Manage XML document namespaces and prefixes
9 |
10 | ## Why?
11 |
12 | Traditionally, creating XML documents with PowerShell is slow, cumbersome and error prone. I discovered this whilst developing the [PScribo](http://github.com/iainbrighton/PScribo) plugin to create Word documents.
13 | After my eyes started to bleed looking at the code, I decided there had to be an easier way and `XmlEx` is a result of this!
14 |
15 | Take the following short XML document as an example:
16 | ```XML
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | ```
32 | To generate this in PowerShell code requires something similar to this:
33 |
34 | ```powershell
35 | $xmlDocument = New-Object -TypeName 'System.Xml.XmlDocument';
36 | $xmlnsMain = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
37 | $null = $xmlDocument.AppendChild($xmlDocument.CreateXmlDeclaration('1.0', 'utf-8', 'yes'));
38 | $documentXml = $xmlDocument.AppendChild($xmlDocument.CreateElement('w', 'document', $xmlnsMain));
39 | $null = $xmlDocument.DocumentElement.SetAttribute('xmlns:xml', 'http://www.w3.org/XML/1998/namespace');
40 |
41 | $body = $documentXml.AppendChild($xmlDocument.CreateElement('w', 'body', $xmlnsMain));
42 |
43 | $p = $body.AppendChild($XmlDocument.CreateElement('w', 'p', $xmlnsMain));
44 | $pPr = $p.AppendChild($XmlDocument.CreateElement('w', 'pPr', $xmlnsMain));
45 |
46 | $pStyle = $pPr.AppendChild($XmlDocument.CreateElement('w', 'pStyle', $xmlnsMain));
47 | $null = $pStyle.SetAttribute('val', $xmlnsMain, 'MyStyle');
48 |
49 | $spacing = $pPr.AppendChild($XmlDocument.CreateElement('w', 'spacing', $xmlnsMain));
50 | $null = $spacing.SetAttribute('before', $xmlnsMain, 160);
51 | $null = $spacing.SetAttribute('after', $xmlnsMain, 160);
52 |
53 | $r = $p.AppendChild($XmlDocument.CreateElement('w', 'r', $xmlnsMain));
54 | $t = $r.AppendChild($XmlDocument.CreateElement('w', 't', $xmlnsMain));
55 | ```
56 | Using `XmlEx`, this can be simply written as:
57 |
58 | ```powershell
59 | $xmlDocument = XmlDocument {
60 | XmlDeclaration -Encoding 'utf-8' -Standalone 'yes'
61 | XmlNamespace -Prefix 'xml' -Uri 'http://www.w3.org/XML/1998/namespace'
62 | XmlElement document -Prefix 'w' -Namespace 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' {
63 | XmlElement 'body' {
64 | XmlElement 'p' {
65 | XmlElement 'pPr' {
66 | XmlElement 'pStyle' {
67 | XmlAttribute 'val' 'MyStyle'
68 | }
69 | XmlElement 'spacing' {
70 | XmlAttribute 'before' '160'
71 | XmlAttribute 'after' '160'
72 | }
73 | }
74 | XmlElement 'r' {
75 | XmlElement 't'
76 | }
77 | }
78 | }
79 | }
80 | }
81 | ```
82 |
83 | ## Quick start
84 |
85 | * Install XmlEx module from the [PowerShell Gallery](https://powershellgallery.com):
86 |
87 | ```powershell
88 | Install-Module -Name XmlEx -Scope CurrentUser
89 | Import-Module XmlEx
90 | ```
91 |
92 | There are examples in module's \Examples folder.
93 |
--------------------------------------------------------------------------------
/Src/Private/Assert-XmlExFile.ps1:
--------------------------------------------------------------------------------
1 | function Assert-XmlExFilePath {
2 | <#
3 | .SYNOPSIS
4 | Ensures the target Xml document XPath does or doesn't exist.
5 |
6 | .DESCRIPTION
7 | Ensures that the specified Xml document XPath location does or does not exist. If the path does not exist, the
8 | cmdlet will create the Xml document XPath.
9 | #>
10 | [CmdletBinding(SupportsShouldProcess)]
11 | param (
12 | # Specifies a path to the Xml document.
13 | [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
14 | [System.String] $Path,
15 |
16 | ## Specifies whether the Xml document should or should not exist.
17 | [Parameter(ValueFromPipelineByPropertyName)]
18 | [ValidateSet('Present','Absent')]
19 | [System.String] $Ensure = 'Present'
20 | )
21 | process {
22 |
23 | if ($Ensure -eq 'Present') {
24 |
25 | if (Test-Path -Path $Path -PathType Leaf) {
26 |
27 | $xmlDocument = New-Object -TypeName System.Xml.XmlDocument;
28 | $xmlDocument.Load($Path);
29 | }
30 | else {
31 |
32 | Write-Verbose -Message ("Xml document '{0}' does not exist. Attempting to create.." -f $Path);
33 |
34 | $parentPath = Split-Path -Path $Path -Parent
35 | if (-not (Test-Path -Path $parentPath -PathType Container)) {
36 |
37 | Write-Verbose -Message ("Parent directory '{0}' does not exist. Attempting to create.." -f $parentPath);
38 | $newItemParams = @{
39 | Path = Split-Path -Path $parentPath -Parent;
40 | Name = Split-Path -Path $parentPath -Leaf;
41 | ItemType = 'Directory';
42 | Force = $true;;
43 | }
44 | [ref] $null = New-Item @newItemParams;
45 | }
46 |
47 | $xmlDocument = New-XmlExDocument -Verbose:$false {
48 |
49 | ## Ensure we have a declaration
50 | Set-XmlExDeclaration
51 | }
52 | }
53 |
54 | return $xmlDocument;
55 |
56 | }
57 | elseif ($Ensure -eq 'Absent') {
58 |
59 | if (Test-Path -Path $Path -PathType Leaf) {
60 |
61 | Write-Verbose -Message ("Xml document '{0}' exists. Attempting to remove.." -f $Path);
62 | Remove-Item -Path $Path -Force;
63 |
64 | }
65 | }
66 |
67 | } #end process
68 | } #end function
69 |
--------------------------------------------------------------------------------
/Src/Private/Assert-XmlExXPath.ps1:
--------------------------------------------------------------------------------
1 | function Assert-XmlExXPath {
2 | <#
3 | .SYNOPSIS
4 | Ensures that the specified XPath and element/attribute is present in an Xml document.
5 | #>
6 | [CmdletBinding(SupportsShouldProcess)]
7 | param (
8 | ## Specifies the Xml document to add the Xml element/attribute to.
9 | [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
10 | [System.Xml.XmlDocument] $XmlDocument,
11 |
12 | ## Specifies the XPath location of the parent Xml element within the document to update.
13 | [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
14 | [System.String] $XPath,
15 |
16 | ## Specifies the name of the Xml element or Xml attribute to update.
17 | [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
18 | [System.String] $Name,
19 |
20 | ## Specifies the value of the Xml element or Xml attribute to update.
21 | [Parameter(ValueFromPipelineByPropertyName)]
22 | [System.String] $Value,
23 |
24 | ## Specifies the target is an attribute. Defaults to an element.
25 | [Parameter(ValueFromPipelineByPropertyName)]
26 | [System.Management.Automation.SwitchParameter] $IsAttribute,
27 |
28 | ## Specifies the target Xml element should be created if it does not exist.
29 | [Parameter(ValueFromPipelineByPropertyName)]
30 | [System.Management.Automation.SwitchParameter] $Force
31 | )
32 | begin {
33 |
34 | $XPath = $XPath.Trim('/');
35 | if (-not $IsAttribute) {
36 |
37 | ## We have an element so ensure it's added to the path..
38 | $XPath = '{0}/{1}' -f $XPath, $Name;
39 | }
40 |
41 | }
42 | process {
43 |
44 | ## Ensure all the path elements exist.
45 | foreach ($xpathNode in $XPath.Split('/')) {
46 |
47 | $currentPath = '{0}/{1}' -f $currentPath, $xpathNode;
48 | $xmlNode = $xmlDocument.SelectSingleNode($currentPath);
49 |
50 | if ($null -eq $xmlNode) {
51 |
52 | ## Create the element
53 | $verboseMessage = $localized.AppendingXmlElementPath -f $currentPath;
54 | $warningConfirmationMessage = $localized.ShouldProcessWarning;
55 | $warningDescriptionMessage = $localized.ShouldProcessOperationWarning -f 'Append', $xpathNode;
56 | if ($Force -or ($PSCmdlet.ShouldProcess($verboseMessage, $warningConfirmationMessage, $warningDescriptionMessage))) {
57 |
58 | $xmlNode = $currentNode.AppendChild($XmlDocument.CreateElement($xpathNode));
59 | }
60 | }
61 |
62 | $currentNode = $xmlNode;
63 |
64 | }
65 |
66 | if ($IsAttribute) {
67 |
68 | ## Create the element
69 | $attributePath = '{0}[@{1}]' -f $currentPath, $xpathNode;
70 | $verboseMessage = $localized.AppendingXmlAttributePath -f $attributePath;
71 | $warningConfirmationMessage = $localized.ShouldProcessWarning;
72 | $warningDescriptionMessage = $localized.ShouldProcessOperationWarning -f 'Append', $attributePath;
73 | if ($Force -or ($PSCmdlet.ShouldProcess($verboseMessage, $warningConfirmationMessage, $warningDescriptionMessage))) {
74 |
75 | Add-XmlExAttribute -Name $Name -Value $Value -XmlElement $currentNode;
76 | }
77 |
78 | }
79 | else {
80 |
81 | $textNodePath = '{0}[#text]' -f $currentPath;
82 | $verboseMessage = $localized.AppendingXmlTextNodePath -f $textNodePath;
83 | $warningConfirmationMessage = $localized.ShouldProcessWarning;
84 | $warningDescriptionMessage = $localized.ShouldProcessOperationWarning -f 'Append', $textNodePath;
85 | if ($Force -or ($PSCmdlet.ShouldProcess($verboseMessage, $warningConfirmationMessage, $warningDescriptionMessage))) {
86 |
87 | if ($currentNode.'#text') {
88 |
89 | # Add-XmlExText appends the value to the text node?!
90 | $currentNode.'#text' = $Value;
91 |
92 | }
93 | else {
94 |
95 | Add-XmlExText -XmlElement $currentNode -Text $Value;
96 |
97 | }
98 |
99 | }
100 |
101 | }
102 |
103 | } #end process
104 | } #end function
105 |
--------------------------------------------------------------------------------
/Src/Private/Resolve-XmlExNamespace.ps1:
--------------------------------------------------------------------------------
1 | function Resolve-XmlExNamespace {
2 | <#
3 | .SYNOPSIS
4 | Resolves supplied prefix/namespace from the XmlEx namespace manager.
5 | .DESCRIPTION
6 | The Resolve-XmlExNamespace method resolves defined Xml namespaces
7 | within the XmlEx document.
8 |
9 | Namespaces can be resolved by prefix or Uri, with Prefix being
10 | checked first. If no match is found, the namespace Uri is checked.
11 | If the namespace is not defined, an entry is not created in the XmlEx
12 | namespace manager, but object is still returned.
13 | #>
14 | [CmdletBinding()]
15 | [OutputType([System.Management.Automation.PSCustomObject])]
16 | param (
17 | ## Namespace prefix
18 | [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Namespace')]
19 | [System.String] $Prefix,
20 |
21 | ## Namespace Uri
22 | [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Namespace')]
23 | [System.String] $Namespace,
24 |
25 | ## Catch-all to enable splatting
26 | [Parameter(ValueFromRemainingArguments)]
27 | [System.Object[]] $RemainingArguments
28 | )
29 | process {
30 |
31 | if ($PSBoundParameters.ContainsKey('Prefix')) {
32 | ## Try matching on Prefix first
33 | foreach ($namespaceKey in $_xmlExDocumentNamespaces.Keys) {
34 |
35 | $ns = $_xmlExDocumentNamespaces[$namespaceKey];
36 | if ($ns.Prefix -eq $Prefix) {
37 | $xmlNamespace = $ns;
38 | break;
39 | }
40 | }
41 | }
42 |
43 | ## If we have no match, try matching on Uri
44 | if (($PSBoundParameters.ContainsKey('Namespace')) -and ($null -eq $xmlNamespace)) {
45 |
46 | foreach ($namespaceKey in $_xmlExDocumentNamespaces.Keys) {
47 |
48 | $ns = $_xmlExDocumentNamespaces[$namespaceKey];
49 | if ($ns.Uri -eq $Namespace) {
50 | $xmlNamespace = $ns;
51 | break;
52 | }
53 | }
54 | }
55 |
56 | if (($null -ne $xmlNamespace) -and ([System.String]::IsNullOrEmpty($xmlNamespace.Prefix))) {
57 |
58 | <#
59 | If we have a defined default namespace, remove the explicit namespace Uri, otherwise we'll end up with
60 | somthing like: d2p1:att2="value2" xmlns:d2p1="http://www.w3.org/XML/1998/namespace" when we add the
61 | object with a namespace.
62 |
63 | We don't want to modify the existing object, so create a new one
64 | #>
65 | $xmlNamespace = [PSCustomObject] @{
66 | Prefix = $null;
67 | Uri = $null;
68 | DisplayName = 'xmlns="{0}"' -f $Namespace;
69 | }
70 | }
71 | elseif ($null -eq $xmlNamespace) {
72 |
73 | ## We have no matching defined namespace, so create an namespace custom object
74 |
75 | $xmlNamespace = [PSCustomObject] @{
76 | Prefix = $Prefix;
77 | Uri = $Namespace;
78 | DisplayName = 'xmlns="{0}"' -f $Namespace;
79 | }
80 |
81 | if ($PSBoundParameters.ContainsKey('Prefix')) {
82 | $XmlNamespace.DisplayName = 'xmlns:{0}="{1}"' -f $Prefix, $Namespace;
83 | }
84 | }
85 |
86 | return $xmlNamespace;
87 |
88 | } #end process
89 | } #end function Resolve-XmlExNamespace
90 |
--------------------------------------------------------------------------------
/Src/Public/Add-XmlExAttribute.ps1:
--------------------------------------------------------------------------------
1 | function Add-XmlExAttribute {
2 | <#
3 | .SYNOPSIS
4 | Adds a XmlAttribute
5 | .DESCRIPTION
6 | The Add-XmlExAttribute cmdlet adds a System.Xml.XmlAttribute to a XmlEx
7 | document or existing System.Xml.XmlDocument object.
8 | #>
9 | [CmdletBinding(DefaultParameterSetName = 'XmlEx')]
10 | [Alias('XmlAttribute')]
11 | [OutputType([System.Xml.XmlAttribute])]
12 | param (
13 | ## Xml attribute name to add
14 | [Parameter(Mandatory, Position = 0, ParameterSetName = 'XmlEx')]
15 | [Parameter(Mandatory, Position = 0, ParameterSetName = 'XmlExNoPrefix')]
16 | [Parameter(Mandatory, Position = 0, ParameterSetName = 'XmlElement')]
17 | [Parameter(Mandatory, Position = 0, ParameterSetName = 'XmlElementNoPrefix')]
18 | [ValidateNotNullOrEmpty()]
19 | [System.String] $Name,
20 |
21 | ## Xml attribute value to add
22 | [Parameter(Mandatory, Position = 1, ParameterSetName = 'XmlEx')]
23 | [Parameter(Mandatory, Position = 1, ParameterSetName = 'XmlExNoPrefix')]
24 | [Parameter(Mandatory, Position = 1, ParameterSetName = 'XmlElement')]
25 | [Parameter(Mandatory, Position = 1, ParameterSetName = 'XmlElementNoPrefix')]
26 | [ValidateNotNull()]
27 | [System.Object] $Value,
28 |
29 | ## Xml namespace assigned to the attribute
30 | [Parameter(ParameterSetName = 'XmlEx')]
31 | [Parameter(ParameterSetName = 'XmlElement')]
32 | [ValidateNotNullOrEmpty()]
33 | [System.Uri] $Namespace,
34 |
35 | ## Xml namespace prefixed assigned to the element
36 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlEx')]
37 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
38 | [ValidateNotNullOrEmpty()]
39 | [System.String] $Prefix,
40 |
41 | ## Existing Xml element to add the attribute to
42 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
43 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElementNoPrefix')]
44 | [ValidateNotNull()]
45 | [System.Xml.XmlElement] $XmlElement,
46 |
47 | ## Returns the create XmlAttrbiute object to the pipeline. By default, this cmdlet does not generate any output.
48 | [Parameter(ValueFromPipelineByPropertyName)]
49 | [System.Management.Automation.SwitchParameter] $PassThru,
50 |
51 | ## Suppresses attribute prefix
52 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlExNoPrefix')]
53 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElementNoPrefix')]
54 | [System.Management.Automation.SwitchParameter] $NoPrefix
55 | )
56 | begin {
57 |
58 | if ($PSCmdlet.ParameterSetName -eq 'XmlElement') {
59 |
60 | Write-Debug ("Inferring document from element '{0}'," -f $Name);
61 | $_xmlExCurrentDocument = $XmlElement.OwnerDocument;
62 | $_xmlExCurrentElement = $XmlElement;
63 | }
64 |
65 | if (($PSBoundParameters.ContainsKey('Namespace')) -or
66 | ($PSBoundParameters.ContainsKey('Prefix'))) {
67 |
68 | [ref] $null = $PSBoundParameters.Remove('Name');
69 | $_xmlExCurrentNamespace = Resolve-XmlExNamespace @PSBoundParameters;
70 | }
71 |
72 | if ($null -eq $_xmlExCurrentDocument) {
73 | throw ($localized.XmlExDocumentNotFoundError);
74 | }
75 |
76 | if ($null -eq $_xmlExCurrentElement) {
77 | throw ($localized.XmlExElementNotFoundError);
78 | }
79 |
80 | } #end begin
81 | process {
82 |
83 | $attributeDisplayName = $Name;
84 | if (-not [System.String]::IsNullOrEmpty($_xmlExCurrentNamespace.Prefix)) {
85 | $attributeDisplayName = '{0}:{1}' -f $_xmlExCurrentNamespace.Prefix, $Name;
86 | }
87 |
88 | $_xmlExCurrentElementIndent ++;
89 | $padding = ''.PadRight($_xmlExCurrentElementIndent);
90 | $paddedMessage = '{0}{1}' -f $padding, ($localized.AddingAttribute -f $attributeDisplayName, $_xmlExCurrentElement.LocalName);
91 | Write-Verbose -Message $paddedMessage;
92 |
93 | if ($NoPrefix) {
94 | $xmlAttribute = $_xmlExCurrentDocument.CreateAttribute($Name);
95 | }
96 | else {
97 | $xmlAttribute = $_xmlExCurrentDocument.CreateAttribute($_xmlExCurrentNamespace.Prefix, $Name, $_xmlExCurrentNamespace.Uri);
98 | }
99 | $xmlAttribute.InnerText = $Value;
100 |
101 | if ($_xmlExCurrentElement -is [System.Xml.XmlDocument]) {
102 |
103 | if ($null -eq $_xmlExCurrentDocument.DocumentElement) {
104 | throw ($localized.XmlExDocumentMissingXmlElementError);
105 | }
106 |
107 | [ref] $null = $_xmlExCurrentDocument.DocumentElement.SetAttributeNode($xmlAttribute);
108 | }
109 | else {
110 |
111 | [ref] $null = $_xmlExCurrentElement.SetAttributeNode($xmlAttribute);
112 | }
113 |
114 | if ($PassThru) {
115 |
116 | Write-Output -InputObject $xmlAttribute;
117 | }
118 |
119 | } #end process
120 | } #end function XmlAttribute
121 |
--------------------------------------------------------------------------------
/Src/Public/Add-XmlExComment.ps1:
--------------------------------------------------------------------------------
1 | function Add-XmlExComment {
2 | <#
3 | .SYNOPSIS
4 | Adds a XmlComment
5 | .DESCRIPTION
6 | The Add-XmlExComment cmdlet adds a System.Xml.XmlComment to a XmlEx
7 | document or existing System.Xml.XmlDocument object.
8 | #>
9 | [CmdletBinding(DefaultParameterSetName = 'XmlEx')]
10 | [Alias('XmlComment')]
11 | [OutputType([System.Xml.XmlComment])]
12 | param (
13 | ## Comment to insert into the Xml document
14 | [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'XmlEx')]
15 | [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'XmlElement')]
16 | [ValidateNotNullOrEmpty()]
17 | [System.String] $Comment,
18 |
19 | ## Existing Xml element to add the comment to
20 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
21 | [ValidateNotNull()]
22 | [System.Xml.XmlElement] $XmlElement,
23 |
24 | ## Adds the comment as the first child of the specified element.
25 | [Parameter(ValueFromPipelineByPropertyName)]
26 | [System.Management.Automation.SwitchParameter] $Prepend,
27 |
28 | ## Returns the XmlComment to the pipeline. By default, this cmdlet does not generate any output.
29 | [Parameter(ValueFromPipelineByPropertyName)]
30 | [System.Management.Automation.SwitchParameter] $PassThru
31 | )
32 | begin {
33 |
34 | if ($PSCmdlet.ParameterSetName -eq 'XmlElement') {
35 |
36 | Write-Debug ("Inferring document from element '{0}'," -f $Name);
37 | $_xmlExCurrentDocument = $XmlElement.OwnerDocument;
38 | $_xmlExCurrentElement = $XmlElement;
39 | }
40 |
41 | if ($null -eq $_xmlExCurrentDocument) {
42 | throw ($localized.XmlExDocumentNotFoundError);
43 | }
44 |
45 | if ($null -eq $_xmlExCurrentElement) {
46 | throw ($localized.XmlExElementNotFoundError);
47 | }
48 |
49 | } #end begin
50 | process {
51 |
52 | $padding = '';
53 | if ($_xmlExCurrentElementIndent) {
54 | $padding = ''.PadRight($_xmlExCurrentElementIndent +1);
55 | }
56 | $paddedMessage = '{0}{1}' -f $padding, ($localized.AddingComment -f $_xmlExCurrentElement.LocalName);
57 | Write-Verbose -Message $paddedMessage;
58 |
59 | $xmlComment = $_xmlExCurrentDocument.CreateComment($Comment);
60 | if ($Prepend) {
61 | [ref] $null = $_xmlExCurrentElement.PrependChild($xmlComment);
62 | }
63 | else {
64 | [ref] $null = $_xmlExCurrentElement.AppendChild($xmlComment);
65 | }
66 |
67 | if ($PassThru) {
68 | Write-Output -InputObject $xmlComment;
69 | }
70 |
71 | } #end process
72 | } #end function XmlComment
73 |
--------------------------------------------------------------------------------
/Src/Public/Add-XmlExElement.ps1:
--------------------------------------------------------------------------------
1 | function Add-XmlExElement {
2 | <#
3 | .SYNOPSIS
4 | Adds a XmlElement
5 | .DESCRIPTION
6 | The Add-XmlExElement cmdlet adds a System.Xml.XmlElement to a XmlEx
7 | document or existing System.Xml.XmlDocument object.
8 | #>
9 | [CmdletBinding(DefaultParameterSetName = 'XmlEx')]
10 | [Alias('XmlElement')]
11 | [OutputType([System.Xml.XmlElement])]
12 | param (
13 | ## Xml element name to add
14 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlEx')]
15 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlElement')]
16 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlDocument')]
17 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlExNoPrefix')]
18 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlElementNoPrefix')]
19 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlDocumentNoPrefix')]
20 | [ValidateNotNullOrEmpty()]
21 | [System.String] $Name,
22 |
23 | ## XmlEx element nested content
24 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlElement')]
25 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlDocument')]
26 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlEx')]
27 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlElementNoPrefix')]
28 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlDocumentNoPrefix')]
29 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlExNoPrefix')]
30 | [ValidateNotNull()]
31 | [System.Management.Automation.ScriptBlock] $ScriptBlock,
32 |
33 | ## Xml namespace assigned to the element
34 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlEx')]
35 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
36 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
37 | [ValidateNotNullOrEmpty()]
38 | [System.Uri] $Namespace,
39 |
40 | ## Xml namespace prefixed assigned to the element
41 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlEx')]
42 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
43 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
44 | [ValidateNotNullOrEmpty()]
45 | [System.String] $Prefix,
46 |
47 | ## Existing Xml element to add the element to
48 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
49 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElementNoPrefix')]
50 | [ValidateNotNull()]
51 | [System.Xml.XmlElement] $XmlElement,
52 |
53 | ## Existing Xml document containing the Xml element to add to
54 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
55 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocumentPrefix')]
56 | [ValidateNotNull()]
57 | [System.Xml.XmlDocument] $XmlDocument,
58 |
59 | ## Returns the created XmlElement object to the pipeline. By default, this cmdlet does not generate any output.
60 | [Parameter(ValueFromPipelineByPropertyName)]
61 | [System.Management.Automation.SwitchParameter] $PassThru,
62 |
63 | ## Suppresses attribute prefix
64 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlExNoPrefix')]
65 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElementNoPrefix')]
66 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocumentPrefix')]
67 | [System.Management.Automation.SwitchParameter] $NoPrefix
68 | )
69 | begin {
70 |
71 | if ($PSCmdlet.ParameterSetName -eq 'XmlDocument') {
72 |
73 | $_xmlExCurrentDocument = $XmlDocument;
74 | $_xmlExCurrentElement = $XmlDocument;
75 | }
76 | elseif ($PSCmdlet.ParameterSetName -eq 'XmlElement') {
77 |
78 | Write-Debug ("Inferring document from element '{0}'," -f $Name);
79 | $_xmlExCurrentDocument = $XmlElement.OwnerDocument;
80 | $_xmlExCurrentElement = $XmlElement;
81 | }
82 |
83 | if (($PSBoundParameters.ContainsKey('Namespace')) -or
84 | ($PSBoundParameters.ContainsKey('Prefix'))) {
85 |
86 | [ref] $null = $PSBoundParameters.Remove('Name');
87 | $_xmlExCurrentNamespace = Resolve-XmlExNamespace @PSBoundParameters;
88 | }
89 |
90 | if ($null -eq $_xmlExCurrentDocument) {
91 | throw ($localized.XmlExDocumentNotFoundError);
92 | }
93 |
94 | if ($null -eq $_xmlExCurrentElement) {
95 | throw ($localized.XmlExElementNotFoundError);
96 | }
97 |
98 | } #end begin
99 | process {
100 |
101 | $elementDisplayName = $Name;
102 | if (-not [System.String]::IsNullOrEmpty($_xmlExCurrentNamespace.Prefix)) {
103 | $elementDisplayName = '{0}:{1}' -f $_xmlExCurrentNamespace.Prefix, $Name;
104 | }
105 |
106 | $_xmlExCurrentElementIndent ++;
107 | $padding = ''.PadRight($_xmlExCurrentElementIndent);
108 | $paddedMessage = '{0}{1}' -f $padding, ($localized.AddingElement -f $elementDisplayName, $_xmlExCurrentElement.LocalName);
109 | Write-Verbose -Message $paddedMessage;
110 |
111 | if ($NoPrefix) {
112 | $xmlElement = $_xmlExCurrentDocument.CreateElement($Name);
113 | }
114 | else {
115 | $xmlElement = $_xmlExCurrentDocument.CreateElement($_xmlExCurrentNamespace.Prefix, $Name, $_xmlExCurrentNamespace.Uri);
116 | }
117 |
118 | $_xmlExCurrentElement = $_xmlExCurrentElement.AppendChild($xmlElement);
119 |
120 | if ($PSBoundParameters.ContainsKey('ScriptBlock')) {
121 | [ref] $null = & $ScriptBlock;
122 | }
123 |
124 | if ($PassThru) {
125 | Write-Output -InputObject $_xmlExCurrentElement;
126 | }
127 |
128 | } #end process
129 | } #end function XmlElement
130 |
--------------------------------------------------------------------------------
/Src/Public/Add-XmlExNamespace.ps1:
--------------------------------------------------------------------------------
1 | function Add-XmlExNamespace {
2 | <#
3 | .SYNOPSIS
4 | Adds a XmlNamespace
5 | .DESCRIPTION
6 | The Add-XmlExNamespace cmdlet adds a Xml namespace to an existing XmlEx
7 | document namespace manager.
8 | #>
9 | [CmdletBinding(DefaultParameterSetName = 'XmlEx')]
10 | [Alias('XmlNamespace')]
11 | param (
12 | ## Xml namespace prefix
13 | [Parameter(ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlEx')]
14 | [Parameter(ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlDocument')]
15 | [ValidateNotNullOrEmpty()]
16 | [System.String] $Prefix,
17 |
18 | ## Xml namespace uniform resource identifer
19 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlEx')]
20 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlDocument')]
21 | [ValidateNotNullOrEmpty()]
22 | [System.Uri] $Uri,
23 |
24 | ## Is the default Xml document namespace, automatically applied to all child elements, attributes and comments etc.
25 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlEx')]
26 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
27 | [ValidateNotNullOrEmpty()]
28 | [System.Management.Automation.SwitchParameter] $IsDefault,
29 |
30 | ## Xml document to add the namespace to
31 | [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
32 | [ValidateNotNull()]
33 | [System.Xml.XmlDocument] $XmlDocument
34 | )
35 | process {
36 |
37 | $callingFunction = (Get-PSCallStack)[2];
38 | if ($callingFunction.FunctionName -ne 'New-XmlExDocument') {
39 | throw ($localized.XmlExInvalidCallOutsideScopeError -f 'XmlNamespace','XmlDocument');
40 | }
41 |
42 | if ($PSBoundParameters.ContainsKey('Prefix')) {
43 | $xmlNamespaceKey = 'xmlns:{0}' -f $Prefix;
44 | }
45 | else {
46 | $xmlNamespaceKey = 'xmlns';
47 | }
48 |
49 | $xmlNamespace = [PSCustomObject] @{
50 | Prefix = $Prefix;
51 | Uri = $Uri.ToString();
52 | DisplayName = '{0}="{1}"' -f $xmlNamespaceKey, $Uri.ToString();
53 | };
54 | Write-Verbose -Message ($localized.SettingDocumentNamespace -f $xmlNamespace.DisplayName);
55 | $_xmlExDocumentNamespaces[$xmlNamespaceKey] = $xmlNamespace;
56 |
57 | if ($IsDefault) {
58 |
59 | Write-Verbose ($localized.SettingDefaultDocumentNamespace -f $xmlNamespace.Uri);
60 | Set-Variable -Name _xmlExCurrentNamespace -Value $xmlNamespace -Scope Script;
61 |
62 | } #end if default
63 |
64 | } #end process
65 | } #end function XmlNamespace
66 |
--------------------------------------------------------------------------------
/Src/Public/Add-XmlExText.ps1:
--------------------------------------------------------------------------------
1 | function Add-XmlExText {
2 | <#
3 | .SYNOPSIS
4 | Adds a XmlText node.
5 | .DESCRIPTION
6 | The Add-XmlExText cmdlet adds a System.Xml.XmlTextNode to a XmlEx
7 | document or existing System.Xml.XmlDocument object.
8 | #>
9 | [CmdletBinding(DefaultParameterSetName = 'XmlEx')]
10 | [Alias('XmlText')]
11 | [OutputType([System.Xml.XmlText])]
12 | param (
13 | ## Xml text to add
14 | [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'XmlEx')]
15 | [Parameter(Mandatory, ValueFromPipeline, Position = 0, ParameterSetName = 'XmlElement')]
16 | [ValidateNotNullOrEmpty()]
17 | [System.String] $Text,
18 |
19 | ## Existing Xml element to add the text node to
20 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlElement')]
21 | [ValidateNotNull()]
22 | [System.Xml.XmlElement] $XmlElement,
23 |
24 | ## Returns the created XmlText object to the pipeline. By default, this cmdlet does not generate any output.
25 | [Parameter(ValueFromPipelineByPropertyName)]
26 | [System.Management.Automation.SwitchParameter] $PassThru
27 | )
28 | begin {
29 |
30 | $callingFunction = (Get-PSCallStack)[2];
31 | if ($callingFunction.FunctionName -eq 'New-XmlExDocument') {
32 | throw ($localized.XmlExInvalidCallWithinScopeError -f 'XmlText','XmlDocument','XmlElement');
33 | }
34 |
35 | if ($PSCmdlet.ParameterSetName -eq 'XmlElement') {
36 |
37 | Write-Debug ("Inferring document from element '{0}'," -f $Name);
38 | $_xmlExCurrentDocument = $XmlElement.OwnerDocument;
39 | $_xmlExCurrentElement = $XmlElement;
40 | }
41 |
42 | if ($null -eq $_xmlExCurrentDocument) {
43 | throw ($localized.XmlExDocumentNotFoundError);
44 | }
45 |
46 | if ($null -eq $_xmlExCurrentElement) {
47 | throw ($localized.XmlExElementNotFoundError);
48 | }
49 |
50 | } #end begin
51 | process {
52 |
53 | $padding = '';
54 | if ($_xmlExCurrentElementIndent) {
55 | $padding = ''.PadRight($_xmlExCurrentElementIndent +1);
56 | }
57 | $paddedMessage = '{0}{1}' -f $padding, ($localized.AddingTextNode -f $_xmlExCurrentElement.LocalName);
58 | Write-Verbose -Message $paddedMessage;
59 |
60 | $xmlTextNode = $_xmlExCurrentDocument.CreateTextNode($Text);
61 | [ref] $null = $_xmlExCurrentElement.AppendChild($xmlTextNode);
62 |
63 | if ($PassThru) {
64 | Write-Output -InputObject $xmlTextNode;
65 | }
66 |
67 | } #end process
68 | } #end function XmlText
69 |
--------------------------------------------------------------------------------
/Src/Public/Format-XmlEx.ps1:
--------------------------------------------------------------------------------
1 | function Format-XmlEx {
2 | <#
3 | .SYNOPSIS
4 | Pretty prints a [System.Xml.XmlDocument] object
5 | .NOTES
6 | https://blogs.msdn.microsoft.com/powershell/2008/01/18/format-xml/
7 | #>
8 | [CmdletBinding()]
9 | param (
10 | ## Xml document to pretty print
11 | [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
12 | [ValidateNotNull()]
13 | [System.Xml.XmlDocument] $XmlDocument,
14 |
15 | ## Xml indentation level
16 | [Parameter()]
17 | [System.Int32] $Indent = 2
18 | )
19 | process {
20 |
21 | $stringReader = New-Object -TypeName 'System.IO.StringReader' -ArgumentList $XmlDocument.OuterXml;
22 | $xmlTextReader = New-Object -TypeName 'System.Xml.XmlTextReader' -ArgumentList $stringReader;
23 |
24 | $stringWriter = New-Object -TypeName 'System.IO.StringWriter';
25 | $xmlTextWriter = New-Object -TypeName 'System.Xml.XmlTextWriter' -ArgumentList $stringWriter;
26 | $xmlTextWriter.Formatting = 'indented';
27 | $xmlTextWriter.Indentation = $Indent;
28 |
29 | do {
30 | $xmlTextWriter.WriteNode($xmlTextReader, $false)
31 | }
32 | while ($xmlTextReader.Read())
33 |
34 | $xmlTextReader.Close();
35 | $stringReader.Close();
36 | $xmlTextWriter.Flush();
37 | $stringWriter.Flush();
38 |
39 | Write-Output -InputObject $stringWriter.ToString();
40 |
41 | } #end process
42 | } #end function Format-XmlEx
43 |
--------------------------------------------------------------------------------
/Src/Public/New-XmlExDocument.ps1:
--------------------------------------------------------------------------------
1 | function New-XmlExDocument {
2 | <#
3 | .SYNOPSIS
4 | Creates a new XmlEx document.
5 | .DESCRIPTION
6 | The New-XmlExDocument cmdlet creates a new XmlEx document.
7 | #>
8 | [CmdletBinding()]
9 | [Alias('XmlDocument')]
10 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
11 | [OutputType([System.Xml.XmlDocument])]
12 | param (
13 | ## XmlEx document content
14 | [Parameter(ValueFromPipelineByPropertyName, Position = 0)]
15 | [ValidateNotNull()]
16 | [System.Management.Automation.ScriptBlock] $ScriptBlock
17 | )
18 | process {
19 |
20 | Write-Verbose -Message ($localized.CreatingDocument);
21 | $_xmlExCurrentDocument = New-Object -TypeName 'System.Xml.XmlDocument';
22 |
23 | $currentWhatIfPreference = $WhatIfPreference;
24 | $WhatIfPreference = $false;
25 | Set-Variable -Name _xmlExCurrentElementIndent -Value 0 -Scope Script;
26 |
27 | ## Set the document namespaces
28 | Set-Variable -Name _xmlExDocumentNamespaces -Value @{ } -Scope Script -Confirm:$false -Force;
29 | Set-Variable -Name _xmlExCurrentNamespace -Value $null -Scope Script;
30 |
31 | ## Set the current element to the root
32 | Set-Variable -Name _xmlExCurrentElement -Value $_xmlExCurrentDocument -Scope Script;
33 | $WhatIfPreference = $currentWhatIfPreference;
34 |
35 | if ($PSBoundParameters.ContainsKey('ScriptBlock')) {
36 | [ref] $null = & $ScriptBlock;
37 | }
38 |
39 | ## We can't add attributes until we have a root element.
40 | foreach ($namespace in $_xmlExDocumentNamespaces.Keys) {
41 |
42 | if ($null -eq $_xmlExCurrentDocument.DocumentElement) {
43 | throw ($localized.XmlExNamespaceMissingXmlElementError);
44 | }
45 | else {
46 |
47 | $xmlNamespace = $_xmlExDocumentNamespaces[$namespace];
48 | Write-Verbose -Message ($localized.AddingDocumentNamespace -f $xmlNamespace.DisplayName);
49 | [ref] $null = $_xmlExCurrentDocument.DocumentElement.SetAttribute(
50 | $namespace, $xmlNamespace.Uri);
51 | }
52 | } #end foreach namespace
53 |
54 | Write-Verbose -Message ($localized.FinalizingDocument);
55 | Write-Output -InputObject $_xmlExCurrentDocument;
56 |
57 | } #end process
58 | } #end functon XmlDocument
59 |
--------------------------------------------------------------------------------
/Src/Public/Set-XmlExConfigKeyValue.ps1:
--------------------------------------------------------------------------------
1 | function Set-XmlExConfigKeyValue {
2 | <#
3 | .SYNOPSIS
4 | Ensures an Xml document contains a Xml element/attribute.
5 | #>
6 | [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Path')]
7 | param (
8 | # Specifies a path to one or more locations. Wildcards are permitted.
9 | [Parameter(Mandatory, Position = 0, ParameterSetName = 'Path', ValueFromPipeline, ValueFromPipelineByPropertyName)]
10 | [ValidateNotNullOrEmpty()]
11 | [SupportsWildcards()]
12 | [System.String[]] $Path,
13 |
14 | # Specifies a path to one or more locations. Unlike the Path parameter, the value of the LiteralPath parameter is
15 | # used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters,
16 | # enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any
17 | # characters as escape sequences.
18 | [Parameter(Mandatory, Position = 0, ParameterSetName = 'LiteralPath', ValueFromPipelineByPropertyName)]
19 | [Alias('PSPath')]
20 | [ValidateNotNullOrEmpty()]
21 | [System.String[]] $LiteralPath,
22 |
23 | ## Specifies the XPath location of the parent Xml element within the document to update.
24 | [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
25 | [System.String] $XPath,
26 |
27 | ## Specifies the name of the Xml element or Xml attribute to update.
28 | [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
29 | [System.String] $Name,
30 |
31 | ## Specifies the value of the Xml element or Xml attribute to update.
32 | [Parameter(ValueFromPipelineByPropertyName)]
33 | [System.String] $Value,
34 |
35 | ## Specifies the target is an attribute. Defaults to an element.
36 | [Parameter(ValueFromPipelineByPropertyName)]
37 | [System.Management.Automation.SwitchParameter] $IsAttribute,
38 |
39 | ## Specifies the target Xml document file should be created if it does not exist.
40 | [Parameter(ValueFromPipelineByPropertyName)]
41 | [System.Management.Automation.SwitchParameter] $Force
42 | )
43 | begin {
44 |
45 | [ref] $null = $PSBoundParameters.Remove('Path');
46 | [ref] $null = $PSBoundParameters.Remove('LiteralPath');
47 | $paths = @();
48 |
49 | }
50 | process {
51 |
52 | if ($PSCmdlet.ParameterSetName -eq 'Path') {
53 |
54 | foreach ($filePath in $Path) {
55 |
56 | if (-not $Force) {
57 |
58 | if (-not (Test-Path -Path $filePath)) {
59 |
60 | $errorMessage = $localized.CannotFindPathError -f $filePath;
61 | $ex = New-Object System.Management.Automation.ItemNotFoundException $errorMessage;
62 | $category = [System.Management.Automation.ErrorCategory]::ObjectNotFound;
63 | $errorRecord = New-Object System.Management.Automation.ErrorRecord $ex, 'PathNotFound', $category, $filePath;
64 | $PSCmdlet.WriteError($errorRecord);
65 | continue;
66 | }
67 |
68 | # Resolve any wildcards that might be in the path
69 | $provider = $null;
70 | $paths += $psCmdlet.SessionState.Path.GetResolvedProviderPathFromPSPath($filePath, [ref] $provider);
71 |
72 | }
73 | else {
74 |
75 | $paths += $PSCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($filePath);
76 |
77 | }
78 |
79 | } #end foreach path
80 | }
81 | else {
82 |
83 | foreach ($filePath in $LiteralPath) {
84 |
85 | if (-not $Force) {
86 |
87 | if (-not (Test-Path -LiteralPath $filePath)) {
88 |
89 | $errorMessage = $localized.CannotFindPathError -f $filePath;
90 | $ex = New-Object System.Management.Automation.ItemNotFoundException $errorMessage;
91 | $category = [System.Management.Automation.ErrorCategory]::ObjectNotFound;
92 | $errorRecord = New-Object System.Management.Automation.ErrorRecord $ex, 'PathNotFound', $category, $filePath;
93 | $PSCmdlet.WriteError($errorRecord);
94 | continue;
95 | }
96 |
97 | }
98 |
99 | # Resolve any relative paths
100 | $paths += $PSCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($filePath);
101 |
102 | } #end foreach literal path
103 | }
104 |
105 | } #end process
106 | end {
107 |
108 | foreach ($filePath in $paths) {
109 |
110 | Write-Verbose -Message ($localized.ProcessingDocument -f $filePath);
111 | $xmlDocument = Assert-XmlExFilePath -Path $filePath -Ensure 'Present';;
112 | Assert-XmlExXPath -XmlDocument $xmlDocument @PSBoundParameters;
113 |
114 | $verboseMessage = $localized.SavingDocument -f $filePath;
115 | $warningConfirmationMessage = $localized.ShouldProcessWarning;
116 | $warningDescriptionMessage = $localized.ShouldProcessOperationWarning -f 'Save', $filePath;
117 |
118 | if ($Force -or ($PSCmdlet.ShouldProcess($verboseMessage, $warningConfirmationMessage, $warningDescriptionMessage))) {
119 |
120 | $xmlDocument.Save($filePath);
121 | }
122 | }
123 |
124 | } #end
125 | } #end function
126 |
--------------------------------------------------------------------------------
/Src/Public/Set-XmlExDeclaration.ps1:
--------------------------------------------------------------------------------
1 | function Set-XmlExDeclaration {
2 | <#
3 | .SYNOPSIS
4 | Sets the Xml declaration.
5 | .DESCRIPTION
6 | The Set-XmlExDeclaration cmdlet set the Xml declaration on a XmlEx document.
7 | #>
8 | [CmdletBinding(DefaultParameterSetName = 'XmlEx')]
9 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')]
10 | [Alias('XmlDeclaration')]
11 | [OutputType([System.Xml.XmlDeclaration])]
12 | param (
13 | ## Xml document 'version' declaration
14 | [Parameter(ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlEx')]
15 | [Parameter(ValueFromPipelineByPropertyName, Position = 0, ParameterSetName = 'XmlDocument')]
16 | [ValidateSet('1.0')]
17 | [System.String] $Version,
18 |
19 | ## Xml document 'encoding' declaration
20 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlEx')]
21 | [Parameter(ValueFromPipelineByPropertyName, Position = 1, ParameterSetName = 'XmlDocument')]
22 | [ValidateNotNullOrEmpty()]
23 | [System.String] $Encoding,
24 |
25 | ## Xml document 'standalone' declaration
26 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlEx')]
27 | [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
28 | [ValidateSet('Yes','No')]
29 | [System.String] $Standalone,
30 |
31 | ## Xml document to add the declaration to
32 | [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'XmlDocument')]
33 | [ValidateNotNull()]
34 | [System.Xml.XmlDocument] $XmlDocument,
35 |
36 | ## Returns the created XmlDecalration object to the pipeline. By default, this cmdlet does not generate any output.
37 | [Parameter(ValueFromPipelineByPropertyName)]
38 | [System.Management.Automation.SwitchParameter] $PassThru
39 | )
40 | begin {
41 |
42 | if ($PSCmdlet.ParameterSetName -eq 'XmlDocument') {
43 | $_xmlExCurrentDocument = $XmlDocument;
44 | }
45 |
46 | if ($null -eq $_xmlExCurrentDocument) {
47 | throw ($localized.XmlExDocumentNotFoundError);
48 | }
49 |
50 | }
51 | process {
52 |
53 | if ($PSCmdlet.ParameterSetName -eq 'XmlEx') {
54 | $callingFunction = (Get-PSCallStack)[2];
55 | if ($callingFunction.FunctionName -ne 'New-XmlExDocument') {
56 | throw ($localized.XmlExInvalidCallOutsideScopeError -f 'XmlDecalration','XmlDocument');
57 | }
58 | }
59 |
60 | if (-not $PSBoundParameters.ContainsKey('Version')) {
61 | $Version = '1.0';
62 | }
63 |
64 | $xmlDeclaration = $_xmlExCurrentDocument.CreateXmlDeclaration($Version, $Encoding, $Standalone);
65 | [ref] $null = $_xmlExCurrentDocument.AppendChild($xmlDeclaration);
66 |
67 | if ($PassThru) {
68 | Write-Output -InputObject $xmlDeclaration;
69 | }
70 |
71 | }
72 | } #end function Set-XmlExDeclaration
73 |
--------------------------------------------------------------------------------
/Tests/Linting/FileEncoding.Tests.ps1:
--------------------------------------------------------------------------------
1 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..").Path;
2 | Describe 'Linting\FileEncoding' {
3 |
4 | $excludedPaths = @(
5 | '.git*',
6 | '.vscode',
7 | 'Docs',
8 | 'DSCResources', # We'll take the public DSC resources as-is
9 | 'Release',
10 | '*.png',
11 | '*.enc',
12 | '*.exe',
13 | '*.dll',
14 | 'appveyor-tools',
15 | 'TestResults.xml'
16 | );
17 |
18 | function TestEncodingPath {
19 | [CmdletBinding()]
20 | param (
21 | [Parameter(Mandatory, ValueFromPipeline)]
22 | [System.String] $Path,
23 |
24 | [System.String[]] $Exclude
25 | )
26 | process
27 | {
28 | $WarningPreference = 'SilentlyContinue'
29 | Get-ChildItem -Path $Path -Exclude $Exclude |
30 | ForEach-Object {
31 | if ($_ -is [System.IO.FileInfo])
32 | {
33 | if ($_.Name -ne 'Resolve-ProgramFilesFolder.ps1')
34 | {
35 | It "File '$($_.FullName.Replace($repoRoot,''))' uses UTF-8 (no BOM) encoding" {
36 | $encoding = (Get-FileEncoding -Path $_.FullName -WarningAction SilentlyContinue).HeaderName
37 | $encoding | Should Be 'us-ascii'
38 | }
39 | }
40 | }
41 | elseif ($_ -is [System.IO.DirectoryInfo])
42 | {
43 | TestEncodingPath -Path $_.FullName -Exclude $Exclude
44 | }
45 | }
46 | } #end process
47 | } #end function
48 |
49 | Get-ChildItem -Path $repoRoot -Exclude $excludedPaths |
50 | ForEach-Object {
51 | TestEncodingPath -Path $_.FullName -Exclude $excludedPaths
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Tests/Linting/PSScriptAnalyzer.Tests.ps1:
--------------------------------------------------------------------------------
1 | #requires -Version 4
2 | #requires -Modules PSScriptAnalyzer
3 |
4 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..").Path;
5 | Describe 'Linting\PSScriptAnalyzer' {
6 |
7 | Get-ChildItem -Path "$repoRoot\Src" -Recurse -File | ForEach-Object {
8 | It "File '$($_.Name)' passes PSScriptAnalyzer rules" {
9 | $result = Invoke-ScriptAnalyzer -Path $_.FullName -Severity Warning | Select-Object -ExpandProperty Message
10 | $result | Should BeNullOrEmpty
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Tests/Linting/Style.Tests.ps1:
--------------------------------------------------------------------------------
1 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..").Path;
2 |
3 | Describe 'Linting\Style' -Tags "Style" {
4 |
5 | $excludedPaths = @(
6 | '.git*',
7 | '.vscode',
8 | 'DSCResources', # We'll take the public DSC resources as-is
9 | 'Release',
10 | '*.png',
11 | '*.enc',
12 | '*.dll',
13 | 'appveyor-tools',
14 | 'TestResults.xml',
15 | 'Tests',
16 | 'Docs'
17 | );
18 |
19 | function TestStylePath {
20 | [CmdletBinding()]
21 | param (
22 | [Parameter(Mandatory, ValueFromPipeline)]
23 | [System.String] $Path,
24 |
25 | [System.String[]] $Exclude
26 | )
27 | process
28 | {
29 | Get-ChildItem -Path $Path -Exclude $Exclude |
30 | ForEach-Object {
31 | if ($_ -is [System.IO.FileInfo])
32 | {
33 | It "File '$($_.FullName.Replace($repoRoot,''))' contains no trailing whitespace" {
34 | $badLines = @(
35 | $lines = [System.IO.File]::ReadAllLines($_.FullName)
36 | $lineCount = $lines.Count
37 |
38 | for ($i = 0; $i -lt $lineCount; $i++) {
39 | if ($lines[$i] -match '\s+$') {
40 | 'File: {0}, Line: {1}' -f $_.FullName, ($i + 1)
41 | }
42 | }
43 | )
44 |
45 | @($badLines).Count | Should Be 0
46 | }
47 |
48 | It "File '$($_.FullName.Replace($repoRoot,''))' ends with a newline" {
49 |
50 | $string = [System.IO.File]::ReadAllText($_.FullName)
51 | ($string.Length -gt 0 -and $string[-1] -ne "`n") | Should Be $false
52 | }
53 | }
54 | elseif ($_ -is [System.IO.DirectoryInfo])
55 | {
56 | TestStylePath -Path $_.FullName -Exclude $Exclude
57 | }
58 | }
59 | } #end process
60 | } #end function
61 |
62 | Get-ChildItem -Path $repoRoot -Exclude $excludedPaths |
63 | ForEach-Object {
64 | TestStylePath -Path $_.FullName -Exclude $excludedPaths
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/Add-XmlExAttribute.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\Add-XmlExAttribute' {
11 |
12 | It 'returns [System.Xml.XmlAttribute] object type' {
13 |
14 | $testAttributeName = 'TestAttribute';
15 | $testAttributeValue = 'TestAttributeValue';
16 | $testComment = 'RequiredToCoerceElementAsXmlElementOtherwiseReturnedAsString';
17 | $testElement = 'TestElement';
18 | $xmlDocument = XmlDocument {
19 | XmlElement -Name $testElement {
20 | XmlComment -Comment $testComment
21 | }
22 | };
23 |
24 | $result = XmlAttribute -Name $testAttributeName -Value $testAttributeValue -XmlElement $xmlDocument.$testElement -PassThru;
25 |
26 | $result -is [System.Xml.XmlAttribute] | Should Be $true;
27 | }
28 |
29 | It 'adds attribute to existing element' {
30 |
31 | $testAttributeName = 'TestAttribute';
32 | $testAttributeValue = 'TestAttributeValue';
33 | $testComment = 'RequiredToCoerceElementAsXmlElementOtherwiseReturnedAsString';
34 | $testElement = 'TestElement';
35 | $expected = '<{0} {1}="{2}">{0}>' -f $testElement, $testAttributeName, $testAttributeValue, $testComment;
36 |
37 | $xmlDocument = XmlDocument {
38 | XmlElement -Name $testElement {
39 | XmlComment -Comment $testComment
40 | }
41 | };
42 | XmlAttribute -Name $testAttributeName -Value $testAttributeValue -XmlElement $xmlDocument.$testElement;
43 |
44 | $xmlDocument.OuterXml | Should Match $expected;
45 | }
46 |
47 | It 'adds attribute in a new document' {
48 |
49 | $testAttributeName = 'TestAttribute';
50 | $testAttributeValue = 'TestAttributeValue';
51 | $testElement = 'TestElement';
52 | $expected = '<{0} {1}="{2}" />' -f $testElement, $testAttributeName, $testAttributeValue;
53 |
54 | $xmlDocument = XmlDocument {
55 | XmlElement -Name $testElement {
56 | XmlAttribute -Name $testAttributeName -Value $testAttributeValue
57 | }
58 | };
59 |
60 | $xmlDocument.OuterXml | Should Match $expected;
61 | }
62 |
63 | It 'adds attribute with a namespace' {
64 |
65 | $testAttributeName = 'TestAttribute';
66 | $testAttributeValue = 'TestAttributeValue';
67 | $testElement = 'TestElement';
68 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace'
69 |
70 | $expectedAttribute = 'd1p1:{0}="{1}"' -f $testAttributeName, $testAttributeValue;
71 | $expectedNamespace = 'xmlns:d1p1="{0}"' -f $testNamespaceUri;
72 |
73 | $xmlDocument = XmlDocument {
74 | XmlElement -Name $testElement {
75 | XmlAttribute -Name $testAttributeName -Value $testAttributeValue -Namespace $testNamespaceUri;
76 | }
77 | };
78 |
79 | $xmlDocument.OuterXml | Should Match $expectedAttribute;
80 | $xmlDocument.OuterXml | Should Match $expectedNamespace;
81 | }
82 |
83 | It 'adds attribute with a prefixed namespace' {
84 |
85 | $testAttributeName = 'TestAttribute';
86 | $testAttributeValue = 'TestAttributeValue';
87 | $testElement = 'TestElement';
88 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace'
89 | $testNamespacePrefix = 'v'
90 |
91 | $expectedAttribute = '{0}:{1}="{2}"' -f $testNamespacePrefix, $testAttributeName, $testAttributeValue;
92 | $expectedNamespace = 'xmlns:{0}="{1}"' -f $testNamespacePrefix, $testNamespaceUri;
93 |
94 | $xmlDocument = XmlDocument {
95 | XmlElement -Name $testElement {
96 | XmlAttribute -Name $testAttributeName -Value $testAttributeValue -Prefix $testNamespacePrefix -Namespace $testNamespaceUri;
97 | }
98 | };
99 |
100 | $xmlDocument.OuterXml | Should Match $expectedAttribute;
101 | $xmlDocument.OuterXml | Should Match $expectedNamespace;
102 | }
103 |
104 | It 'does not add attribute prefix when specified' {
105 | $testAttributeName = 'TestAttribute';
106 | $testAttributeValue = 'TestAttributeValue';
107 | $testElement = 'TestElement';
108 | $testPrefix = 've';
109 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace'
110 |
111 | $xmlDocument = XmlDocument {
112 | XmlNamespace -Prefix $testPrefix -Uri $testNamespaceUri -IsDefault
113 | XmlElement -Name $testElement -Namespace $testNamespaceUri {
114 | XmlAttribute -Name $testAttributeName -Value $testAttributeValue -NoPrefix
115 | }
116 | };
117 | $xmlDocument.OuterXml | Should Not Match "$($testprefix):$($testAttributeName)"
118 | }
119 |
120 | It 'throws when adding attribute when document contains no root element' {
121 |
122 | $testAttributeName = 'TestAttribute';
123 | $testAttributeValue = 'TestAttributeValue';
124 | {
125 | XmlDocument {
126 | XmlAttribute -Name $testAttributeName -Value $testAttributeValue
127 | }
128 | } | Should Throw "Cannot add a 'XmlAttribute' to a document without a root element";
129 | }
130 |
131 | } #end describe Src\Add-XmlExAttribute
132 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/Add-XmlExComment.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\Add-XmlExComment' {
11 |
12 | It 'returns [System.Xml.XmlComment] object type' {
13 |
14 | $testComment = 'Test Comment';
15 | $xmlDocument = XmlDocument {
16 | XmlElement -Name 'TestElement' {
17 | XmlAttribute -Name 'RequiredToCoerceElementAsXmlElement' -Value 'OtherwiseReturnedAsString'
18 | }
19 | };
20 |
21 | $result = XmlComment -Comment $testComment -XmlElement $xmlDocument.TestElement -PassThru;
22 |
23 | $result -is [System.Xml.XmlComment] | Should Be $true;
24 | }
25 |
26 | It 'creates "" comment' {
27 |
28 | $testComment = 'Test Comment';
29 | $expected = '' -f $testComment;
30 |
31 | $result = XmlDocument {
32 | XmlComment $testComment
33 | };
34 |
35 | $result.OuterXml | Should Match $expected;
36 |
37 | }
38 |
39 | } #end describe Src\Add-XmlExComment
40 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/Add-XmlExElement.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\Add-XmlExElement' {
11 |
12 | It 'returns [System.Xml.XmlElement] object type' {
13 |
14 | $testElement = 'TestElement';
15 | $xmlDocument = XmlDocument { };
16 |
17 | $result = XmlElement $testElement -XmlDocument $xmlDocument -PassThru;
18 |
19 | $result -is [System.Xml.XmlElement] | Should Be $true;
20 | }
21 |
22 | It 'creates an element' {
23 |
24 | $testElement = 'TestElement';
25 | $testComment = 'RequiredToCoerceAcceleratorToXmlElement';
26 | $expected = '<{0}>{0}' -f $testElement, $testComment;
27 | $result = XmlDocument {
28 | XmlElement $testElement {
29 | XmlComment $testComment
30 | }
31 | }
32 |
33 | $result.OuterXml | Should Match $expected;
34 | }
35 |
36 | It 'calls nested "ScriptBlock"' {
37 |
38 | $testRootElement = 'TestRootElement';
39 | $testNestedElement = 'TestNestedElement';
40 | $testComment = 'RequiredToCoerceAcceleratorToXmlElement';
41 | $expected = '<{0}><{1}>{1}>{0}' -f $testRootElement, $testNestedElement, $testComment;
42 |
43 | $result = XmlDocument {
44 | XmlElement $testRootElement {
45 | XmlElement -Name $testNestedElement {
46 | XmlComment $testComment
47 | }
48 | }
49 | }
50 |
51 | $result.OuterXml | Should Match $expected;
52 | }
53 |
54 | It 'creates an element with a namespace' {
55 |
56 | $testElement = 'TestElement';
57 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace';
58 | $expected = '<{0} xmlns="{1}" />' -f $testElement, $testNamespaceUri;
59 | $result = XmlDocument {
60 | XmlElement $testElement -Namespace $testNamespaceUri
61 | }
62 |
63 | $result.OuterXml | Should Match $expected;
64 | }
65 |
66 | It 'creates an element with a prefixed namespace' {
67 |
68 | $testElement = 'TestElement';
69 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace';
70 | $testNamespacePrefix = 'v';
71 | $expected = '<{0}:{1} xmlns:{0}="{2}" />' -f $testNamespacePrefix, $testElement, $testNamespaceUri;
72 | $result = XmlDocument {
73 | XmlElement $testElement -Prefix $testNamespacePrefix -Namespace $testNamespaceUri
74 | }
75 |
76 | $result.OuterXml | Should Match $expected;
77 | }
78 |
79 | It 'adds an element to an existing [XmlElement]' {
80 | $testRootElement = 'TestRootElement';
81 | $testNestedElement = 'TestNestedElement';
82 | $testComment = 'RequiredToCoerceAcceleratorToXmlElement';
83 | $expected = '<{0}><{2} />{0}>' -f $testRootElement, $testComment, $testNestedElement;
84 | $xmlDocument = XmlDocument {
85 | XmlElement $testRootElement {
86 | XmlComment $testComment
87 | }
88 | }
89 |
90 | $null = XmlElement -Name $testNestedElement -XmlElement $xmlDocument.$testRootElement
91 | $xmlDocument.OuterXml | Should Match $expected;
92 | }
93 |
94 | It 'does not add element prefix when specified' {
95 | $testElement = 'TestElement';
96 | $nestedTestElement = 'NestedTestElement';
97 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace';
98 | $testNamespacePrefix = 'v';
99 | $expected = '<{0} />' -f $nestedTestElement;
100 |
101 | $xmlDocument = XmlDocument {
102 | XmlElement $testElement -Prefix $testNamespacePrefix -Namespace $testNamespaceUri {
103 | XmlElement -Name $nestedTestElement -NoPrefix
104 | }
105 | }
106 |
107 | $xmlDocument.OuterXml | Should Match $expected
108 | }
109 |
110 | } #end describe Src\Add-XmlExElement
111 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/Add-XmlExNamespace.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\Add-XmlExNamespace' {
11 |
12 | It 'Creates [System.Xml.XmlDocument] with a namespace' {
13 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace';
14 | $expected = 'xmlns="{0}"' -f $testNamespaceUri;
15 |
16 | $result = XmlDocument {
17 | XmlNamespace -Uri $testNamespaceUri;
18 | XmlElement 'RequiredToAddNamespace';
19 | };
20 |
21 | $result.OuterXml | Should Match $expected;
22 | }
23 |
24 | It 'Creates [System.Xml.XmlDocument] with a prefixed namespace' {
25 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace';
26 | $testNamespacePrefix = 've';
27 | $expected = 'xmlns:{0}="{1}"' -f $testNamespacePrefix, $testNamespaceUri;
28 |
29 | $result = XmlDocument {
30 | XmlNamespace -Prefix $testNamespacePrefix -Uri $testNamespaceUri;
31 | XmlElement 'RequiredToAddNamespace';
32 | };
33 |
34 | $result.OuterXml | Should Match $expected;
35 | }
36 |
37 | It 'throws when calling "XmlNamespace" outside of "XmlDocument" script block' {
38 | $testNamespaceUri = 'http://virtualengine.co.uk/namespace';
39 | $xmlDocument = XmlDocument { };
40 |
41 | { XmlNamespace -Uri 'http://virtualengine.co.uk/namespace' -XmlDocument $xmlDocument } |
42 | Should Throw "You cannot call 'XmlNamespace' outside the 'XmlDocument' scope.";
43 | }
44 |
45 | } #end describe Src\Add-XmlExNamespace
46 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/Add-XmlExText.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\Add-XmlExText' {
11 |
12 | It 'returns [System.Xml.XmlText] object type' {
13 |
14 | $testText = 'Test text';
15 | $testElement = 'TestElement';
16 | $xmlDocument = XmlDocument {
17 | XmlElement -Name testElement {
18 | XmlAttribute -Name 'RequiredToCoerceElementAsXmlElement' -Value 'OtherwiseReturnedAsString'
19 | }
20 | };
21 |
22 | $result = XmlText -Text $testText -XmlElement $xmlDocument.$testElement -PassThru;
23 |
24 | $result -is [System.Xml.XmlText] | Should Be $true;
25 | }
26 |
27 | It 'creates element text node' {
28 |
29 | $testText = 'Test text';
30 | $testElement = 'TestElement';
31 | $expected = '<{0}>{1}{0}>' -f $testElement, $testText;
32 |
33 | $result = XmlDocument {
34 | XmlElement $testElement {
35 | XmlText $testText
36 | }
37 | };
38 |
39 | $result.OuterXml | Should Match $expected;
40 |
41 | }
42 |
43 | It 'throws when adding text to the document root' {
44 |
45 | $testText = 'Test text';
46 |
47 | {
48 | XmlDocument {
49 | XmlText $testText
50 | }
51 | } | Should Throw "You cannot call 'XmlText' from within the 'XmlDocument' scope"
52 | }
53 |
54 | } #end describe Src\Add-XmlText
55 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/New-XmlExDocument.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\New-XmlExDocument' {
11 |
12 | It 'creates a [System.Xml.XmlDocument] object type' {
13 |
14 | $result = XmlDocument;
15 |
16 | $result -is [System.Xml.XmlDocument] | Should Be $true;
17 | }
18 |
19 | It 'calls nested "ScriptBlock"' {
20 |
21 | $testComment = 'Test Comment'
22 |
23 | $result = XmlDocument { XmlComment $testComment };
24 |
25 | $result.OuterXml | Should Match $testComment;
26 | }
27 |
28 | It 'throws adding "XmlNamespace" to an empty "XmlDocument"' {
29 |
30 | { XmlDocument {
31 | XmlNamespace -Uri 'http://virtualengine.co.uk/namespace'
32 | }
33 | } | Should Throw "Cannot add a 'XmlNamespace' to a document without a root element.";
34 |
35 | }
36 |
37 | } #end describe Src\New-XmlExDocument
38 |
--------------------------------------------------------------------------------
/Tests/Unit/Src/Public/Set-XmlExDeclaration.Tests.ps1:
--------------------------------------------------------------------------------
1 | [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingCmdletAliases', '')]
2 | param()
3 |
4 | #requires -Version 3
5 |
6 | $moduleName = 'XmlEx';
7 | $repoRoot = (Resolve-Path "$PSScriptRoot\..\..\..\..").Path;
8 | Import-Module (Join-Path -Path $repoRoot -ChildPath "$moduleName.psm1") -Force;
9 |
10 | Describe 'Src\Set-XmlExDeclaration' {
11 |
12 | It 'returns [System.Xml.XmlDeclaration] object type' {
13 |
14 | $xmlDocument = XmlDocument { }
15 |
16 | $result = XmlDeclaration -XmlDocument $xmlDocument -PassThru;
17 |
18 | $result -is [System.Xml.XmlDeclaration] | Should Be $true;
19 | }
20 |
21 | It 'adds version number by default' {
22 |
23 | $expected = 'version="1.0"';
24 |
25 | $result = XmlDocument {
26 | XmlDeclaration
27 | }
28 |
29 | $result.OuterXml | Should Match $expected;
30 | }
31 |
32 | It 'adds encoding declaration when specified' {
33 |
34 | $testEncoding = 'utf-8';
35 | $expected = 'encoding="{0}"' -f $testEncoding;
36 |
37 | $result = XmlDocument {
38 | XmlDeclaration -Encoding $testEncoding
39 | }
40 |
41 | $result.OuterXml | Should Match $expected;
42 | }
43 |
44 | It 'adds standalone declaration when specified' {
45 |
46 | $testStandalone = 'yes';
47 | $expected = 'standalone="{0}"' -f $testStandalone;
48 |
49 | $result = XmlDocument {
50 | XmlDeclaration -Standalone $testStandalone
51 | }
52 |
53 | $result.OuterXml | Should Match $expected;
54 | }
55 |
56 | It 'throws when called outside the XmlDocument scope' {
57 |
58 | {
59 | XmlDocument {
60 | XmlElement 'notallowed' {
61 | XmlDeclaration
62 | }
63 | }
64 | } | Should Throw "You cannot call 'XmlDecalration' outside the 'XmlDocument' scope";
65 | }
66 |
67 | } #end describe Src\Set-XmlExDeclaration
68 |
--------------------------------------------------------------------------------
/VE_Certificate_2019.pfx.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iainbrighton/XmlEx/4a686180edcef207ef571cb7dbc57f6d8f12bd49/VE_Certificate_2019.pfx.enc
--------------------------------------------------------------------------------
/XmlEx.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | xmlex
5 | XmlEx
6 | 0.0.0
7 | Iain Brighton
8 | Virtual Engine
9 | The XmlEx module implements a simple PowerShell DSL for XML documents.
10 | The XmlEx module implements a simple PowerShell DSL for the creation and manipulation of XML documents.
11 | http://github.com/iainbrighton/XmlEx
12 | (c) 2018 Virtual Engine Limited. All rights reserved.
13 | MIT
14 | false
15 | XML Powerhell DSL Extension Framework
16 |
17 |
18 |
--------------------------------------------------------------------------------
/XmlEx.psd1:
--------------------------------------------------------------------------------
1 | @{
2 | RootModule = 'XmlEx.psm1';
3 | ModuleVersion = '0.9.5';
4 | GUID = '2a98010d-0e5f-4779-b3b5-5f0b66fea533';
5 | Author = 'Iain Brighton';
6 | CompanyName = 'Virtual Engine';
7 | Copyright = '(c) 2018 Iain Brighton. All rights reserved.';
8 | Description = 'The XmlEx module implements a simple PowerShell DSL for the creation and manipulation of XML documents.';
9 | PowerShellVersion = '3.0';
10 | AliasesToExport = @(
11 | 'XmlAttribute',
12 | 'XmlComment',
13 | 'XmlDeclaration',
14 | 'XmlDocument',
15 | 'XmlElement',
16 | 'XmlNamespace',
17 | 'XmlText'
18 | );
19 | FunctionsToExport = @(
20 | 'Add-XmlExAttribute',
21 | 'Add-XmlExComment',
22 | 'Add-XmlExElement',
23 | 'Add-XmlExNamespace',
24 | 'Add-XmlExText',
25 | 'Format-XmlEx',
26 | 'New-XmlExDocument',
27 | 'Set-XmlExDeclaration',
28 | 'Set-XmlExConfigKeyValue'
29 | );
30 | PrivateData = @{
31 | PSData = @{ # Private data to pass to the module specified in RootModule/ModuleToProcess
32 | Tags = @('XML','Powershell','Extension','DSL','Framework');
33 | LicenseUri = 'https://github.com/IainBrighton/XmlEx/blob/master/LICENSE';
34 | ProjectUri = 'https://github.com/IainBrighton/XmlEx';
35 | IconUri = 'https://raw.githubusercontent.com/IainBrighton/XmlEx/master/xml-tool-icon-53260.png';
36 | } # End of PSData hashtable
37 | } # End of PrivateData hashtable
38 | }
39 |
--------------------------------------------------------------------------------
/XmlEx.psm1:
--------------------------------------------------------------------------------
1 | ## Import localisation strings
2 | if (Test-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath $PSUICulture))
3 | {
4 | $importLocalizedDataParams = @{
5 | FileName = 'XmlEx.Resources.psd1';
6 | BaseDirectory = Join-Path -Path $PSScriptRoot -ChildPath $PSUICulture;
7 | }
8 | }
9 | else
10 | {
11 | # fallback to en-US
12 | $importLocalizedDataParams = @{
13 | FileName = 'XmlEx.Resources.psd1';
14 | UICulture = 'en-US';
15 | BaseDirectory = Join-Path -Path $PSScriptRoot -ChildPath 'en-US';
16 | }
17 | }
18 | Import-LocalizedData -BindingVariable 'localized' @importLocalizedDataParams;
19 |
20 | ## Import the \Lib files. This permits loading of the module's functions for unit testing, without having to unload/load the module.
21 | $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path -Parent;
22 | $moduleSrcPath = Join-Path -Path $moduleRoot -ChildPath 'Src';
23 | Get-ChildItem -Path $moduleSrcPath -Include '*.ps1' -Recurse |
24 | ForEach-Object {
25 | Write-Verbose -Message ('Importing library\source file ''{0}''.' -f $_.FullName);
26 | . $_.FullName;
27 | }
28 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | #---------------------------------#
2 | # environment configuration #
3 | #---------------------------------#
4 |
5 | version: 0.9.{build}
6 | environment:
7 | gallery_api_key:
8 | secure: WeDp1yZJECZBjjW+22A8lA8+gmz+wiYostPKtU4pdLXORfK//eJCdR7f0k3oJ+2r
9 | certificate_secret:
10 | secure: 2NeBUwfDSJomxCyxUlwnqw==
11 |
12 | install:
13 | - ps: Write-Verbose -Message "PowerShell version $($PSVersionTable.PSVersion)" -Verbose
14 | - ps: Install-Module -Name Pester, PSSCriptAnalyzer, PSake, VirtualEngine.Build -Scope CurrentUser -Force -AllowClobber -Verbose
15 | - ps: $null = Invoke-Expression ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1'))
16 |
17 | build: false
18 |
19 | on_finish:
20 | - ps: |
21 | Invoke-PSake -BuildFile .\Build.PSake.ps1 -TaskList Appveyor
22 |
23 | for:
24 |
25 | -
26 | branches:
27 | only:
28 | - dev
29 |
30 | test_script:
31 | - ps: |
32 | Invoke-PSake -BuildFile .\Build.PSake.ps1 -TaskList Test
33 | Write-Verbose "PSake.build_success: $($psake.build_success)" -Verbose
34 | if (-not $psake.build_success) { exit 1 }
35 |
36 | -
37 | branches:
38 | only:
39 | - master
40 |
41 | test_script:
42 | - ps: |
43 | Invoke-PSake -BuildFile .\Build.PSake.ps1 -TaskList Publish
44 | Write-Verbose "PSake.build_success: $($psake.build_success)" -Verbose
45 | if (-not $psake.build_success) { exit 1 }
46 |
--------------------------------------------------------------------------------
/en-US/XmlEx.Resources.psd1:
--------------------------------------------------------------------------------
1 | # en-US
2 | ConvertFrom-StringData @'
3 | CreatingDocument = Creating XmlEx document.
4 | SettingDocumentNamespace = Setting document namespace to '{0}'.
5 | SettingDocumentNamespaceWithPrefix = Setting document namespace '{0}' with prefix '{1}'.
6 | SettingDefaultDocumentNamespace = Setting default document namespace '{0}'.
7 | AddingElement = Adding element '{0}' to element '{1}'.
8 | AddingAttribute = Adding attribute '{0}' to element '{1}'.
9 | AddingTextNode = Adding text node to element '{0}'.
10 | AddingComment = Adding comment to element '{0}'.
11 | AddingDocumentNamespace = Adding document namespace '{0}'.
12 | FinalizingDocument = Finalizing XmlEx document.
13 |
14 | ProcessingDocument = Process Xml document '{0}'.
15 | AppendingXmlElementPath = Appending Xml element/path '{0}'.
16 | AppendingXmlAttributePath = Appending attribute '{0}'.
17 | AppendingXmlTextNodePath = Appending text node '{0}'.
18 | SavingDocument = Saving Xml document '{0}'.
19 |
20 | XmlExDocumentNotFoundError = XmlEx document not found/reference not set.
21 | XmlExElementNotFoundError = XmlEx element not found/reference not set.
22 | XmlExNamespaceMissingXmlElementError = Cannot add a 'XmlNamespace' to a document without a root element.
23 | XmlExDocumentMissingXmlElementError = Cannot add a 'XmlAttribute' to a document without a root element.
24 | XmlExInvalidCallOutsideScopeError = You cannot call '{0}' outside the '{1}' scope.
25 | XmlExInvalidCallWithinScopeError = You cannot call '{0}' from within the '{1}' scope. '{0}' must be nested within a '{2}' scope.
26 | CannotFindPathError = Cannot find path '{0}' because it does not exist.
27 |
28 | ShouldProcessOperationWarning = Performing operation "{0}" on Target "{1}".
29 | ShouldProcessWarning = Continue with this operation?
30 | '@;
31 |
--------------------------------------------------------------------------------
/xml-tool-icon-53260.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iainbrighton/XmlEx/4a686180edcef207ef571cb7dbc57f6d8f12bd49/xml-tool-icon-53260.png
--------------------------------------------------------------------------------