0

Can anyone explain me why I can get data from the xml file if I use this:

[xml]$configXml = Get-Content -Path "c:\test.xml"
$configXml.Config.Client.Servers.Server.name

Output: srv1

But if I use it inside a module, I get no data at all:

[xml]$configXml = Get-Content -Path "c:\test.xml"

function global:XTR_GetXmlConfig{
Param(
    [Parameter(Mandatory=$true)]
    $Option
)

    return $configXml.Config.$Option
}

XTR_GetXmlConfig -Option Client.Servers.Server.name

only the first node retrives data using the module:

XTR_GetXmlConfig -Option Client

My xml is very basic:

?xml version="1.0" encoding="UTF-8"?>
<Config>
    <Client>
        <Domain>test.pt</Domain>
        <Servers>
            <Server>
                <Name>srv1<Name>
                <IP>192.168.0.1</IP>
            </Server>
            <Server>
                <Name>srv2</Name>
                <IP>192.168.0.2</IP>
            </Server>
            <Server>
                <Name>srv3</Name>
                <IP>192.168.0.3</IP>
            </Server>
        </Servers>
    </Client>
</Config>
3
  • I guess because your function is declared in a higher scope (global) than the variable (script). Commented Oct 27, 2016 at 13:44
  • i have also tried setting both to global... same behaviour... and I think it is not necessary because I am only accessing the variable xml inside the module Commented Oct 27, 2016 at 13:57
  • Line seven "7" of the .xml file needs to have the ending tag start with a / character. There should also be a < as the first character of the file. Commented Oct 27, 2016 at 16:30

2 Answers 2

2

@Mike Garuccio's answer is right. But, I'm not sure that there needs to be that much work done on the $Option string. Also, I made the top level part of the parameter to keep it out of the function. How about...?

[cmdletbinding()]
Param()

[xml]$configXml = Get-Content -Path ".\xmltest.xml"

function global:XTR_GetXmlConfig {
Param(
    [Parameter(Mandatory=$true)]
    $Option
)
    Invoke-Expression "return `$configXml.$option"
}

XTR_GetXmlConfig -Option Config.Client.Servers.Server.name
Sign up to request clarification or add additional context in comments.

3 Comments

Yep this is better, I'd already gone down the track of separating out the properties and didn't think to try it with a single string like I should have, upvoted your answer and this is the one that should be accepted.
@Liturgist I'm still working my way through powershell. Can you explain me why you have used the Param() and [cmdletbinding()] in the top of the module ? I thought the parameters were only used in function... also I intend to use the variable inside the module, that way It will be available to all the functions created in it. Please correct me if I'm wrong. Thank you
Those extras at the top enable standard switches like -Verbose to be used.
2

The problem here is that it is trying to treat your entire $option variable as the property to access rather than moving down through the tree (think of it trying to evaluate like below)

$configXml.Config.'Client.Servers.Server.name'

Theres probably a better way to deal with that but below is what I came up with, basically it builds the command to run from scratch and then invokes it, generated a plain list of server names on my machine.  Hope this helps.

[xml]$configXml = Get-Content -Path "test.xml"

function XTR_GetXmlConfig{
 Param(
[Parameter(Mandatory=$true)]
$Option
)
$options = $option.split('.')
[string]$command = 'return $configXml.Config'
foreach($o in $options){
    $command += ".$($o)"
}

Invoke-Expression $command
}

XTR_GetXmlConfig -Option Client.Servers.Server.name

Sorry for the formatting, powershell never wants to paste in correctly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.