简体   繁体   中英

Powershell script to search an XML sub-elements

Hello I'm having problem trying to get the values of one node with certain name from XML.

For example:

<Smart>
  <Settings>
    <Service name="9003">
       <Config imports="router">
           <Section name="x">
                <Parameter name="a" value="0" />
                <Parameter name="b" value="1" />
                <Parameter name="c" value="2" />
                <Parameter name="d" value="3" />
                <Parameter name="e" value="4" />
           </Section>
        </Config>
    </Service>
    <Service name="9004">
       <Config imports="router">
           <Section name="x">
                <Parameter name="a" value="5" />
                <Parameter name="b" value="6" />
                <Parameter name="c" value="7" />
                <Parameter name="d" value="8" />
                <Parameter name="e" value="9" />
           </Section>
        </Config>
    </Service>
  </Settings>
</Smart>

I want to get the value '9' from the Parameter named as "e" from the Service "9004" and then export or print it using the Write-Host.

Any ideas? I was trying this but it is returning nothing to me.

    # Read the XML file
    Write-Host "OPENING XML FILE";
    $path = "\\$computer\$FileName"
    [xml] $xml = Get-Content $path
    
    # Filter the XML
    $SectionName = "x"
    $Section = $xml.Smart.Settings.Config.Section| Where-Object {$_.name -eq $SectionName}
    Write-Host $Section

@Brazs, try using XPath to select the element based on the path and name value, like so

$parameterElement = $xml.SelectSingleNode("//Section[@name='$SectionName']/Parameter[@name='e']")

You can get to the attribute value directly like this

$parameterElement.value

or with a method

$parameterElement.GetAttribute('value')

EDIT: The search criteria can be expanded too, so

$parameterElement = $xml.SelectSingleNode("//Service[@name='$ServiceName']/Config/Section[@name='$SectionName']/Parameter[@name='e']")

finds the required service, any config, the required section and the 'e' Parameter. I leave it to you to figure out how to expand on that for a specific config or variable Parameter, for example.

A bit of a different approach to allow you to dynamically cherry-pick as needed.

[xml]$XmlData = @'
<Smart>
  <Settings>
    <Config imports="alpha">
        <Section name="x">
           <Parameter name="a" value="true" />
           <Parameter name="b" value="0" />
           <Parameter name="c" value="13873" />
           <Parameter name="d" value="true" />
           <Parameter name="e" value="EAI" />
        </Section>
        <Section name="y">
           <Parameter name="a" value="false" />
           <Parameter name="b" value="1" />
           <Parameter name="c" value="13874" />
           <Parameter name="d" value="false" />
           <Parameter name="e" value="EAI1" />
        </Section>
    </Config>
  </Settings>
</Smart>
'@


($SectionData = Select-Xml -Xml $XmlData -XPath '//Section').Node 
# Results
<#
name Parameter      
---- ---------      
x    {a, b, c, d, e}
y    {a, b, c, d, e}
#>

$SectionData.Node.SyncRoot | 
Where-Object name -eq 'x' 
# Results
<#
name Parameter      
---- ---------      
x    {a, b, c, d, e}
#>


($SectionData.Node.SyncRoot | 
Where-Object name -eq 'x').Parameter | 
Where-Object name -eq 'e'
# Results
<#
name value
---- -----
e    EAI 
#>


(($SectionData.Node.SyncRoot | 
Where-Object name -eq 'x').Parameter | 
Where-Object name -eq 'e').Value
# Results
<#
EAI
#>

Using your numbers XMLData, then this:

(((($SectionData.Node.SyncRoot | 
Where-Object name -eq '9003').Config).Section).Parameter | 
Where-Object -Property name -eq 'e').Value
# Results
<#
4
#>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM