TOGEEK
TOGEEK

Reputation: 741

Need to filter XML files based on XML attribute AND list the LastWriteTime

I have this relatively straightforward script to list a directory of approx. 2000 XML files, and I wish to limit the list to those with a specific attribute node called Order, with a value of '2017-01-10'.

While I can achieve this, I also need the LastWriteTime of the matching file.

So here is the result when returning the files (limited the result to just one):

PS> gci $path 

Mode                LastWriteTime     Length Name
----                -------------     ------
-a---          1/9/2017  12:39 PM       6643 File.xml

And then using XPath to retrieve the node value:

PS> gci $path | Select-Xml -XPath "//Order[contains(@OrderDate,'2017-01-10')]"

Node        Path                    Pattern
----        ----                    -------
Order       \\<Path>\file.xml       //Order[contains(@OrderDate,'2017-01-10')]

But I need to combine the two scripts, so that I have the list of files only with the required node value, but also showing the LastWriteTime. It doesn't seem to like adding a Select LastWriteTime within the same line as the Select-Xml. Almost as if I'm using a "Where-Xml" if it existed.

Upvotes: 0

Views: 1092

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200383

If you want to add a particular property from an upstream object to the output of Select-Xml you can do so with a calculated property like this:

Get-ChildItem $path | ForEach-Object {
  $file = $_
  Select-Xml -Path $file.FullName -XPath "//Order[contains(@OrderDate,'2017-01-10')]" |
    Select-Object -Property *,@{n='LastWriteTime';e={$file.LastWriteTime}}
}

Or you could create a custom object with just the properties you need:

Get-ChildItem $path | ForEach-Object {
  $node = Select-Xml -Path $_.FullName -XPath "//Order[contains(@OrderDate,'2017-01-10')]"

  $prop = [ordered]@{
    FullName      = $_.FullName
    LastWriteTime = $_.LastWriteTime
    Node          = $node.Node
  }
  New-Object -Type PSObject -Property $prop
}

Or (if you actually want the file list, not the node list, as output, just filtered by particular content of the files) you could run the Select-Xml in a Where-Object filter:

Get-ChildItem $path | Where-Object {
  Select-Xml -Path $_.FullName -XPath "//Order[contains(@OrderDate,'2017-01-10')]"
}

Upvotes: 1

Related Questions