EightBitz
November 4th, 2016, 11:50 PM
There was a recent post by Rob where he indicated there was an upcoming export feature for XML, and if nothing else, this would allow us to print. This offers the possibility that we'll have to roll our own print formatting. Not something I'm thrilled about, but hey, I'll take what I can get.
I've been poking around with XML features in PowerShell, and some of it is easier than I thought it would be while some of it is still a bit frustrating. I'm not a professional programmer, but I dabble, and I know there are others who wish to print, so I'm sharing what I'm learning in my struggles. If anyone else with more programming experience wishes to chime in, I'm all for that.
If you're going to follow along with me, I suggest loading the PowerShell ISE. It's not installed by default, but you can install it through the "Add or remove programs" control panel and selecting "Turn Windows Features on or off." Find "PowerShell ISE", and select it. (I'm assuming you're using Windows 8 or Windows 10.)
And just to clarify, this isn't meant to be an in-depth, comprehensive tutorial. I'm learning as I go, so this is a very basic introduction for myself that I'm sharing with you.
First of all, importing an XML file into PowerShell as an XML object is rather easy. To practice, I'm working with a Hero Lab portfolio, hence my variable name in the following code snippet. I'm also using a Mutants and Masterminds 3E portfolio with multiple characters.
(Paste this in the top half of the ISE window.)
[xml]$Portfolio = Get-Content -Path <filename>
That's it. That loads the file as an XML object. Click the green play button to run the script.
Now, in the bottom window, you can type "$Portfolio" and press the enter key. You'll see the child nodes ("xml" and "document") as column headers.
Now type "$Portfolio.document.public" (I'm skipping ahead with the child nodes), and you'll see the child nodes for program, localization and character. Under the character column, you'll see the list of character names in curly brackets. Mine have spaces in the names (e.g. "The Rook").
So now, in the top half, I can add the following code to the script:
$Rook = $Portfolio.document.public.character | Where-Object {$_.name -eq "The Rook"}
Now, if I type $Rook in the bottom half of the ISE window, I can see a list of the child nodes and their values for this single character.
Now, say I want to get The Rook's attributes. In Mutants and Masterminds 3E, the attributes are Strength, Stamina, Agility and Dexterity. And for each attribute, the available elements are: text, base, modified, cost.
So if I want to get The Rook's strength, I can add the following code to the script.
$Strength = $Rook.attributes.attribute | Where-Object {$_.name -eq "Strength"}
Now, in the bottom half of the ISE window, I can type $Strength, and I'll see the different values. Or I can type $Strength.text, $Strength.base, $Strength.modified, or Strength.cost.
This is basically how you can drill-down through the XML object to get the values you want. To see the full hierarchy, you can load the XML file into UltraEdit (License required) or NotePad++ (Free) or something similar.
I wrote a recursive function that does kind of a raw text dump. It's not pretty, but if you want to play with the function, here it is:
Function ShowXML($PassedObject,$PassedOutput,$PassedIndent) {
"$PassedIndent### " + $PassedObject.name + " ###" >> $PassedOutput
if ($PassedObject.innertext -ne "") {
$PassedIndent + $PassedObject.innertext >> $PassedOutput
} elseif ($PassedParam.text -ne "") {
$PassedIndent + $PassedObject.text >> $PassedOutput
} # if ($PassedObject.innertext)
if ($PassedObject.HasChildNodes) {
$PassedIndent = $PassedIndent + " "
foreach ($Child in $PassedObject.ChildNodes) {
ShowXML $Child $PassedOutput $PassedIndent
} # foreach ($Child in $PassedObject.ChildNodes)
} # if ($PassedObject.HasChildNodes)
} # Function ShowXML
# Main Script Starts Here
$InputFile = "<Original XML filename>"
$OutputFile = "<File to contain the raw dump>"
[xml]$Portfolio = Get-Content -Path $InputFile
"XML Output" > $OutputFile
$Indent = ""
ShowXML $Portfolio $OutputFile $Indent
I've been poking around with XML features in PowerShell, and some of it is easier than I thought it would be while some of it is still a bit frustrating. I'm not a professional programmer, but I dabble, and I know there are others who wish to print, so I'm sharing what I'm learning in my struggles. If anyone else with more programming experience wishes to chime in, I'm all for that.
If you're going to follow along with me, I suggest loading the PowerShell ISE. It's not installed by default, but you can install it through the "Add or remove programs" control panel and selecting "Turn Windows Features on or off." Find "PowerShell ISE", and select it. (I'm assuming you're using Windows 8 or Windows 10.)
And just to clarify, this isn't meant to be an in-depth, comprehensive tutorial. I'm learning as I go, so this is a very basic introduction for myself that I'm sharing with you.
First of all, importing an XML file into PowerShell as an XML object is rather easy. To practice, I'm working with a Hero Lab portfolio, hence my variable name in the following code snippet. I'm also using a Mutants and Masterminds 3E portfolio with multiple characters.
(Paste this in the top half of the ISE window.)
[xml]$Portfolio = Get-Content -Path <filename>
That's it. That loads the file as an XML object. Click the green play button to run the script.
Now, in the bottom window, you can type "$Portfolio" and press the enter key. You'll see the child nodes ("xml" and "document") as column headers.
Now type "$Portfolio.document.public" (I'm skipping ahead with the child nodes), and you'll see the child nodes for program, localization and character. Under the character column, you'll see the list of character names in curly brackets. Mine have spaces in the names (e.g. "The Rook").
So now, in the top half, I can add the following code to the script:
$Rook = $Portfolio.document.public.character | Where-Object {$_.name -eq "The Rook"}
Now, if I type $Rook in the bottom half of the ISE window, I can see a list of the child nodes and their values for this single character.
Now, say I want to get The Rook's attributes. In Mutants and Masterminds 3E, the attributes are Strength, Stamina, Agility and Dexterity. And for each attribute, the available elements are: text, base, modified, cost.
So if I want to get The Rook's strength, I can add the following code to the script.
$Strength = $Rook.attributes.attribute | Where-Object {$_.name -eq "Strength"}
Now, in the bottom half of the ISE window, I can type $Strength, and I'll see the different values. Or I can type $Strength.text, $Strength.base, $Strength.modified, or Strength.cost.
This is basically how you can drill-down through the XML object to get the values you want. To see the full hierarchy, you can load the XML file into UltraEdit (License required) or NotePad++ (Free) or something similar.
I wrote a recursive function that does kind of a raw text dump. It's not pretty, but if you want to play with the function, here it is:
Function ShowXML($PassedObject,$PassedOutput,$PassedIndent) {
"$PassedIndent### " + $PassedObject.name + " ###" >> $PassedOutput
if ($PassedObject.innertext -ne "") {
$PassedIndent + $PassedObject.innertext >> $PassedOutput
} elseif ($PassedParam.text -ne "") {
$PassedIndent + $PassedObject.text >> $PassedOutput
} # if ($PassedObject.innertext)
if ($PassedObject.HasChildNodes) {
$PassedIndent = $PassedIndent + " "
foreach ($Child in $PassedObject.ChildNodes) {
ShowXML $Child $PassedOutput $PassedIndent
} # foreach ($Child in $PassedObject.ChildNodes)
} # if ($PassedObject.HasChildNodes)
} # Function ShowXML
# Main Script Starts Here
$InputFile = "<Original XML filename>"
$OutputFile = "<File to contain the raw dump>"
[xml]$Portfolio = Get-Content -Path $InputFile
"XML Output" > $OutputFile
$Indent = ""
ShowXML $Portfolio $OutputFile $Indent