1

I'm trying to select a node in PowerShell which exist more then once. I declared the namespaces and try to select with XPath without success. I only get back NULL.

I'm not sure what I did wrong but I can select all settings with

$selectedNode = $xml.SelectSingleNode("//ns:settings[@pass='oobeSystem']", $NSMGR)

but I want to reach component with the attribute @name="Microsoft-Windows-Shell-Setup". I tried different ways, but the result is always NULL.

Code snippet:

$NSMGR = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
#$NSMGR.AddNamespace("ns", $xml.DocumentElement.NamespaceURI) default
$NSMGR.AddNamespace("ns", "urn:schemas-microsoft-com:unattend")
$NSMGR.AddNamespace("xsi", "http://www.w3.org/2001/xmlSchema-instance") 

#first try
$selectedNode = $xml.SelectSingleNode("//ns:settings[@pass='oobeSystem']/component[@name='Microsoft-Windows-International-Core']", $NSMGR)
$selectedNode = $xml.SelectSingleNode("//ns:settings[@pass='oobeSystem']/xsi:component[@name='Microsoft-Windows-International-Core']", $NSMGR)
$selectedNode

#second try
$selectedNode = $xml.SelectSingleNode("//ns:settings[@pass='oobeSystem']", $NSMGR)
$selectedNode = $selectedNode.SelectSingleNode("//ns:component[@name='Microsoft-Windows-Shell-Setup']", $NSMGR) #Edit to MS Shell instead of internal core for my example
$selectedNode

XML snippet:

<?xml version="1.0" encoding="utf-8" ?>
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:ew="urn:schemas-microsoft-com:embedded.unattend.internal.v1">
  <settings pass="specialize">
    <component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <ComputerName>*</ComputerName>
      <TimeZone>UTC</TimeZone>
    </component>
    <component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <InputLocale>0407:00000407</InputLocale>
      <UILanguage>en-US</UILanguage>
      <SystemLocale>en-US</SystemLocale>
      <UserLocale>en-US</UserLocale>
      <UILanguageFallback>de-DE</UILanguageFallback>
    </component>
  </settings>
  <settings pass="oobeSystem">
    <component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <OOBE>
        <ProtectYourPC>3</ProtectYourPC>
        <NetworkLocation>Work</NetworkLocation>
        <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
      </OOBE>
    </component>
    <component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Embedded-Core-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <HideEvaluationWarning>1</HideEvaluationWarning>
    </component>
  </settings>
  <settings pass="windowsPE">
    <component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <SetupUILanguage>
        <UILanguage>en-US</UILanguage>
        <WillShowUI>OnError</WillShowUI>
      </SetupUILanguage>
      <UserLocale>en-US</UserLocale>
      <UILanguage>en-US</UILanguage>
      <InputLocale>0407:00000407</InputLocale>
      <SystemLocale>en-US</SystemLocale>
    </component>
  </settings>
</unattend>
2
  • 1
    You create the namespace manager for namespaces from a variable $xmlNewUnattend, but select nodes from a variable $xml. Your second attempt worked fine for me when I created the namespace manager from $xml as well. Commented Feb 10, 2016 at 18:33
  • yes you are right, i just reduce the size and forgot to rename $xmlNewUnattend to $xml for my example. Ok in that syntax its right, but when you try to select "Microsoft-Windows-Shell-Setup" instead of internal core it will select the first node inside of the file but i want to catch the one under "oobeSystem". So my second try doesn't work properly Commented Feb 11, 2016 at 8:31

1 Answer 1

1

Select the desired childnode relative to the particular parent node, like this:

$selectedNode = $xml.SelectSingleNode("//ns:settings[@pass='oobeSystem']/ns:component[@name='Microsoft-Windows-Shell-Setup']", $NSMGR)

or like this:

$parentNode = $xml.SelectSingleNode("//ns:settings[@pass='oobeSystem']", $NSMGR)
$selectedNode = $parentNode.SelectSingleNode("./ns:component[@name='Microsoft-Windows-Shell-Setup']", $NSMGR)

Note that you need to use the ns: namespace for both the parent and the child node.

Sign up to request clarification or add additional context in comments.

3 Comments

It works..! :) i'm quiete sure that i try your way before but maybe there was an other issue at the moment so that this doesn't worked for me... Great thanks a lot :)
@black Perhaps you used a wrong component name? Your "first try" example uses the component name Microsoft-Windows-International-Core, but there is no component with that name under the node <settings pass="oobeSystem">.
No, there is one in the full xmlfile. but i create it and use it afterwards. during creation it adds an attribute xlmns="" after that i was able to select this node without using the second ns:. But this only worked for nodes with xlmns="" (<component name="X" ... xlmns="">)in his tag. maybe this was the reason why i was confused about how it works. Now i delete all empty xlmns="" tags and use your solution and it works as it should :)

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.