PowerShell遍历XML层级:提取含KeySecret的Node及所属Domain名称
Got it, let's tackle this problem. The tricky part here is that your XML stores "attributes" like name and keySecret as child <Property> nodes instead of direct attributes on the <Object> elements, which is why your initial XPath attempts probably fell flat. Here's how to get the data you need in PowerShell:
Step 1: Load the XML Content
First, load your XML into a PowerShell XML object. You can either read it from a file or use a variable with the raw XML string:
# Option 1: From a file $xml = Get-Content -Path "your-xml-file.xml" -Raw | [xml] # Option 2: From a raw string (using your sample XML) $xmlContent = @' <?xml version="1.0"?> <Object id="1.1622157565" type="Domain"> <Property type="String" name="name" value="ROOTDOMAIN"/> <Object id="1.1131962319" type="Node"> <Property type="String" name="name" value="AGENTLESS NODE 1"/> </Object> <Object id="1.1132169655" type="Domain"> <Property type="String" name="name" value="SUBDOMAIN"/> <Object id="1.1132121638" type="Node"> <Property type="BigNum" name="keySecret" value="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"/> <Property type="String" name="name" value="AGENT NODE 1"/> </Object> </Object> </Object> '@ $xml = [xml]$xmlContent
Step 2: Target the Correct Nodes and Extract Data
Use Select-Xml with a precise XPath query to find all <Object> nodes of type Node that have a keySecret property, then traverse up to their closest parent Domain node to get the domain name:
# Find all Node objects that have a keySecret property $targetNodes = Select-Xml -Xml $xml -XPath '//Object[@type="Node"][./Property[@name="keySecret"]]' # Process each node to extract Domain and Node names $results = foreach ($node in $targetNodes.Node) { # Get the closest parent Domain object $parentDomain = $node.SelectSingleNode('ancestor::Object[@type="Domain"][1]') # Extract the Node's name from its Property child $nodeName = $node.SelectSingleNode('./Property[@name="name"]').GetAttribute('value') # Extract the Domain's name from its Property child $domainName = $parentDomain.SelectSingleNode('./Property[@name="name"]').GetAttribute('value') # Create a custom object for clean output [PSCustomObject]@{ Domain = $domainName Node = $nodeName } } # Output the results as a formatted table $results | Format-Table -AutoSize
Expected Output
Running the above script will produce exactly the table you're looking for:
| Domain | Node |
|---|---|
| SUBDOMAIN | AGENT NODE 1 |
Why Your Initial XPath Failed
Your original XPath likely tried to reference attributes directly (like @keySecret), but in this XML structure, those values are stored in child <Property> nodes with a name attribute matching the "property name" and a value attribute holding the actual data. The XPath we use specifically checks for the presence of that child node, then traverses up the hierarchy to find the nearest parent Domain node.
内容的提问来源于stack exchange,提问作者Peter Jensen

